From 04111f06c66f6f935651903e85bda36d6f05d349 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 25 Apr 2024 12:47:39 +0200 Subject: improve build/flash instructions --- main/makefile | 22 ++++++++++++++++++++++ main/readme.md | 21 +++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 main/makefile create mode 100644 main/readme.md (limited to 'main') diff --git a/main/makefile b/main/makefile new file mode 100644 index 0000000..833fd02 --- /dev/null +++ b/main/makefile @@ -0,0 +1,22 @@ +# this file is for lazy people (loek) + +.PHONY: FORCE + +all: FORCE build/main.uf2 + +build/build.ninja: CMakeLists.txt + mkdir -p build + cmake -B build -G Ninja + +build/main.uf2: build/build.ninja FORCE + ninja -C build +# ninja automatically builds in parallel, so is preferred + +flash: build/main.uf2 FORCE + picotool load -fx $< +# -f forces a reboot of the pico before flashing +# -x resets the pico after flashing + +clean: FORCE + $(RM) -r build + diff --git a/main/readme.md b/main/readme.md new file mode 100644 index 0000000..425a00b --- /dev/null +++ b/main/readme.md @@ -0,0 +1,21 @@ +# main controller firmware + +This directory contains the software for the main controller of the Puzzle Box. + +## building + +1. make sure the submodules are initialized +2. copy [`config.def.h`](./config.def.h) to `config.h` and edit the defaults +3. `mkdir build` +4. `cmake -B build` +5. `make -C build` or `ninja -C build` (choose your preference) + +alternatively, a makefile is provided for convenience + +## "flashing" + +1. [build](#building) +2. (re)connect the raspberry pi pico while holding the BOOTSEL button (this is + the only button) +3. `picotool load build/main.uf2` + -- cgit v1.2.3 From 0ef1ae11846bfcbbd63e22d1dfecf579f4069c80 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 25 Apr 2024 14:28:45 +0200 Subject: WIP FreeRTOS --- .gitmodules | 5 ++++ main/CMakeLists.txt | 19 ++++++++----- main/FreeRTOSConfig.h | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ main/lib/FreeRTOS-Kernel | 1 + main/main.cpp | 29 +++++++++++++------- main/makefile | 2 +- 6 files changed, 108 insertions(+), 17 deletions(-) create mode 100644 main/FreeRTOSConfig.h create mode 160000 main/lib/FreeRTOS-Kernel (limited to 'main') diff --git a/.gitmodules b/.gitmodules index c951407..58b768d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,3 +8,8 @@ url = https://github.com/google/googletest branch = v1.14.0 shallow = true +[submodule "main/lib/FreeRTOS-Kernel"] + path = main/lib/FreeRTOS-Kernel + url = https://github.com/FreeRTOS/FreeRTOS-Kernel + branch = V11.1.0 + shallow = true diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index e24d9a5..590d516 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,22 +1,29 @@ cmake_minimum_required(VERSION 3.29) -include(lib/pico-sdk/pico_sdk_init.cmake) - -project(puzzlebox_main C CXX ASM) - set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 17) set(CMAKE_EXPORT_COMPILE_COMMANDS 1) set(PICO_BOARD pico_w) +include(lib/pico-sdk/pico_sdk_init.cmake) +include(lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake) + +project(puzzlebox_main C CXX ASM) + pico_sdk_init() add_executable(main main.cpp -) + ) pico_enable_stdio_usb(main 1) # pico_enable_stdio_uart(main 1) pico_add_extra_outputs(main) + target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR}) -target_link_libraries(main pico_cyw43_arch_lwip_threadsafe_background pico_stdlib) +target_link_libraries(main + pico_cyw43_arch_lwip_threadsafe_background + pico_stdlib + FreeRTOS-Kernel + ) + diff --git a/main/FreeRTOSConfig.h b/main/FreeRTOSConfig.h new file mode 100644 index 0000000..305bcb4 --- /dev/null +++ b/main/FreeRTOSConfig.h @@ -0,0 +1,69 @@ +#pragma once +// values from pico-examples/pico_w/wifi/freertos + +#define configUSE_PREEMPTION 1 +#define configUSE_TICKLESS_IDLE 0 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configTICK_RATE_HZ ((TickType_t) 1000) +#define configMAX_PRIORITIES 32 +#define configMINIMAL_STACK_SIZE ((configSTACK_DEPTH_TYPE) 256) +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configUSE_QUEUE_SETS 1 +#define configUSE_TIME_SLICING 1 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 +#define configSTACK_DEPTH_TYPE uint32_t +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE (128 * 1024) +#define configAPPLICATION_ALLOCATED_HEAP 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 1 +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH 1024 + +// #define configNUM_CORES 2 +// #define configTICK_CORE 0 +// #define configRUN_MULTIPLE_PRIORITIES 1 +// #define configUSE_CORE_AFFINITY 1 + +#define configSUPPORT_PICO_SYNC_INTEROP 1 +#define configSUPPORT_PICO_TIME_INTEROP 1 + +#include +#define configASSERT(x) assert(x) + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_xQueueGetMutexHolder 1 + diff --git a/main/lib/FreeRTOS-Kernel b/main/lib/FreeRTOS-Kernel new file mode 160000 index 0000000..dbf7055 --- /dev/null +++ b/main/lib/FreeRTOS-Kernel @@ -0,0 +1 @@ +Subproject commit dbf70559b27d39c1fdb68dfb9a32140b6a6777a0 diff --git a/main/main.cpp b/main/main.cpp index 9fd3123..d118de2 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,12 +1,23 @@ -#include - #include "config.h" -#include "pico/stdlib.h" -#include "pico/cyw43_arch.h" +#include +#include + +#include +#include +#include const unsigned int LED_PIN = CYW43_WL_GPIO_LED_PIN; +void blink_task() { + while (true) { + cyw43_arch_gpio_put(LED_PIN, 0); + sleep_ms(250); + cyw43_arch_gpio_put(LED_PIN, 1); + sleep_ms(250); + } +} + int main() { stdio_init_all(); sleep_ms(2000); @@ -16,6 +27,8 @@ int main() { return 1; } cyw43_arch_gpio_put(LED_PIN, 1); + + printf("initialised\n"); cyw43_arch_enable_sta_mode(); @@ -26,11 +39,7 @@ int main() { } printf("connected\n"); - while (true) { - cyw43_arch_gpio_put(LED_PIN, 0); - sleep_ms(250); - cyw43_arch_gpio_put(LED_PIN, 1); - sleep_ms(250); - } + xTaskCreate((TaskFunction_t) blink_task, "blink", 128, NULL, 1, NULL); + vTaskStartScheduler(); } diff --git a/main/makefile b/main/makefile index 833fd02..1986cd3 100644 --- a/main/makefile +++ b/main/makefile @@ -6,7 +6,7 @@ all: FORCE build/main.uf2 build/build.ninja: CMakeLists.txt mkdir -p build - cmake -B build -G Ninja + cmake -B build -G Ninja --fresh --log-level WARNING build/main.uf2: build/build.ninja FORCE ninja -C build -- cgit v1.2.3 From 42b3b8abd73d0f38efd607fc9dfcf768341549a1 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 25 Apr 2024 15:10:43 +0200 Subject: freertos works --- main/CMakeLists.txt | 1 + main/FreeRTOSConfig.h | 10 +++++++++- main/main.cpp | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'main') diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 590d516..29afb84 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -25,5 +25,6 @@ target_link_libraries(main pico_cyw43_arch_lwip_threadsafe_background pico_stdlib FreeRTOS-Kernel + FreeRTOS-Kernel-Heap4 ) diff --git a/main/FreeRTOSConfig.h b/main/FreeRTOSConfig.h index 305bcb4..4897d8d 100644 --- a/main/FreeRTOSConfig.h +++ b/main/FreeRTOSConfig.h @@ -1,6 +1,10 @@ #pragma once // values from pico-examples/pico_w/wifi/freertos +#ifdef __cplusplus +extern "C" { +#endif + #define configUSE_PREEMPTION 1 #define configUSE_TICKLESS_IDLE 0 #define configUSE_IDLE_HOOK 0 @@ -25,7 +29,7 @@ #define configSUPPORT_STATIC_ALLOCATION 0 #define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configTOTAL_HEAP_SIZE (128 * 1024) -#define configAPPLICATION_ALLOCATED_HEAP 0 +#define configAPPLICATION_ALLOCATED_HEAP 4 #define configCHECK_FOR_STACK_OVERFLOW 0 #define configUSE_MALLOC_FAILED_HOOK 0 #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 @@ -67,3 +71,7 @@ #define INCLUDE_xTaskResumeFromISR 1 #define INCLUDE_xQueueGetMutexHolder 1 +#ifdef __cplusplus +} // extern "C" +#endif + diff --git a/main/main.cpp b/main/main.cpp index d118de2..8b3504c 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -12,9 +12,9 @@ const unsigned int LED_PIN = CYW43_WL_GPIO_LED_PIN; void blink_task() { while (true) { cyw43_arch_gpio_put(LED_PIN, 0); - sleep_ms(250); + vTaskDelay(250 / portTICK_PERIOD_MS); cyw43_arch_gpio_put(LED_PIN, 1); - sleep_ms(250); + vTaskDelay(250 / portTICK_PERIOD_MS); } } -- cgit v1.2.3 From 6df58f546db68047fe38f3809ee4f6cbff4c6f89 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 25 Apr 2024 15:54:24 +0200 Subject: clean up init --- main/CMakeLists.txt | 1 + main/config.def.h | 8 +++++++- main/init.cpp | 32 ++++++++++++++++++++++++++++++++ main/init.h | 5 +++++ main/main.cpp | 27 +++------------------------ 5 files changed, 48 insertions(+), 25 deletions(-) create mode 100644 main/init.cpp create mode 100644 main/init.h (limited to 'main') diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 29afb84..7c18f56 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -14,6 +14,7 @@ pico_sdk_init() add_executable(main main.cpp + init.cpp ) pico_enable_stdio_usb(main 1) diff --git a/main/config.def.h b/main/config.def.h index 48de559..376c58a 100644 --- a/main/config.def.h +++ b/main/config.def.h @@ -1,8 +1,14 @@ #pragma once +#include +// wifi credentials #define CONF_NET_SSID "network name" #define CONF_NET_PASS "network password" +// max duration (milliseconds) for establishing wifi connection +#define CONF_NET_CONN_TIMEOUT 10000 -#include "cyw43_country.h" +#include #define CONF_NET_COUNTRY CYW43_COUNTRY_NETHERLANDS +#define LED_PIN CYW43_WL_GPIO_LED_PIN + diff --git a/main/init.cpp b/main/init.cpp new file mode 100644 index 0000000..425f591 --- /dev/null +++ b/main/init.cpp @@ -0,0 +1,32 @@ +#include "config.h" +#include "init.h" + +#include +#include + +static void init_stdio() { + stdio_init_all(); +} + +static void init_cyw34() { + if (cyw43_arch_init_with_country(CONF_NET_COUNTRY)) + panic("cyw43_arch_init_with_country failed\n"); +} + +static void init_wifi() { + // enable 'station' mode (connect to an access point instead of acting like one) + cyw43_arch_enable_sta_mode(); + + if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CYW43_AUTH_WPA2_AES_PSK, CONF_NET_CONN_TIMEOUT)) + panic("cyw43_arch_wifi_connect failed\n"); + + // TODO: announce hostname +} + +void init() { + init_stdio(); + init_cyw34(); + init_wifi(); + // TODO: initialize i2c +} + diff --git a/main/init.h b/main/init.h new file mode 100644 index 0000000..1f931dc --- /dev/null +++ b/main/init.h @@ -0,0 +1,5 @@ +#pragma once + +/** @brief initialize all peripherals on the pico */ +void init(); + diff --git a/main/main.cpp b/main/main.cpp index 8b3504c..d85c76e 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,13 +1,10 @@ -#include "config.h" - #include #include #include -#include -#include -const unsigned int LED_PIN = CYW43_WL_GPIO_LED_PIN; +#include "config.h" +#include "init.h" void blink_task() { while (true) { @@ -19,25 +16,7 @@ void blink_task() { } int main() { - stdio_init_all(); - sleep_ms(2000); - - if (cyw43_arch_init_with_country(CONF_NET_COUNTRY)) { - printf("failed to initialize\n"); - return 1; - } - cyw43_arch_gpio_put(LED_PIN, 1); - - - printf("initialised\n"); - - cyw43_arch_enable_sta_mode(); - - if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CYW43_AUTH_WPA2_AES_PSK, 10000)) { - printf("failed to connect\n"); - return 1; - } - printf("connected\n"); + init(); xTaskCreate((TaskFunction_t) blink_task, "blink", 128, NULL, 1, NULL); vTaskStartScheduler(); -- cgit v1.2.3 From cee744e2bd419c0fc47f2b8bb315f183929d1113 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 25 Apr 2024 17:30:41 +0200 Subject: WIP making LwIP and FreeRTOS friends --- main/CMakeLists.txt | 4 +++- main/config.def.h | 2 ++ main/lwipopts.h | 10 ++-------- main/main.cpp | 17 +++++++++++++++-- 4 files changed, 22 insertions(+), 11 deletions(-) (limited to 'main') diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 7c18f56..27b3822 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -18,9 +18,11 @@ add_executable(main ) pico_enable_stdio_usb(main 1) -# pico_enable_stdio_uart(main 1) +pico_enable_stdio_uart(main 0) pico_add_extra_outputs(main) +include_directories(lib/pico-sdk/lib/lwip/contrib/ports/freertos/include) + target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR}) target_link_libraries(main pico_cyw43_arch_lwip_threadsafe_background diff --git a/main/config.def.h b/main/config.def.h index 376c58a..c6852ef 100644 --- a/main/config.def.h +++ b/main/config.def.h @@ -10,5 +10,7 @@ #include #define CONF_NET_COUNTRY CYW43_COUNTRY_NETHERLANDS +#define CONF_SRV_PORT 9191 + #define LED_PIN CYW43_WL_GPIO_LED_PIN diff --git a/main/lwipopts.h b/main/lwipopts.h index 75a57ee..71c85b2 100644 --- a/main/lwipopts.h +++ b/main/lwipopts.h @@ -1,13 +1,7 @@ #pragma once -// allow override in some examples -#ifndef NO_SYS -#define NO_SYS 1 -#endif - -#ifndef LWIP_SOCKET -#define LWIP_SOCKET 0 -#endif +#define NO_SYS 0 +#define LWIP_SOCKET 1 #if PICO_CYW43_ARCH_POLL #define MEM_LIBC_MALLOC 1 diff --git a/main/main.cpp b/main/main.cpp index d85c76e..d9d5e56 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2,10 +2,15 @@ #include #include +#include #include "config.h" #include "init.h" +#include +#include +#include + void blink_task() { while (true) { cyw43_arch_gpio_put(LED_PIN, 0); @@ -18,7 +23,15 @@ void blink_task() { int main() { init(); - xTaskCreate((TaskFunction_t) blink_task, "blink", 128, NULL, 1, NULL); - vTaskStartScheduler(); + for (int i = 5; i > 0; i--) { + printf("starting in %d...\n", i); + sleep_ms(1000); + } + + // this should compile but not work + lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + // xTaskCreate((TaskFunction_t) blink_task, "blink", 128, NULL, 1, NULL); + // vTaskStartScheduler(); } -- cgit v1.2.3 From efc9870fb1ddd286954fc056b79dddf39f68353a Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 9 May 2024 12:06:07 +0200 Subject: freertos + lwip compile working --- main/CMakeLists.txt | 2 +- main/FreeRTOSConfig.h | 12 ++---------- main/lwipopts.h | 13 +++++++++++++ main/main.cpp | 4 ++-- 4 files changed, 18 insertions(+), 13 deletions(-) (limited to 'main') diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 27b3822..b86c077 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -25,7 +25,7 @@ include_directories(lib/pico-sdk/lib/lwip/contrib/ports/freertos/include) target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR}) target_link_libraries(main - pico_cyw43_arch_lwip_threadsafe_background + pico_cyw43_arch_lwip_sys_freertos pico_stdlib FreeRTOS-Kernel FreeRTOS-Kernel-Heap4 diff --git a/main/FreeRTOSConfig.h b/main/FreeRTOSConfig.h index 4897d8d..c811296 100644 --- a/main/FreeRTOSConfig.h +++ b/main/FreeRTOSConfig.h @@ -1,17 +1,13 @@ #pragma once // values from pico-examples/pico_w/wifi/freertos -#ifdef __cplusplus -extern "C" { -#endif - #define configUSE_PREEMPTION 1 #define configUSE_TICKLESS_IDLE 0 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configTICK_RATE_HZ ((TickType_t) 1000) #define configMAX_PRIORITIES 32 -#define configMINIMAL_STACK_SIZE ((configSTACK_DEPTH_TYPE) 256) +#define configMINIMAL_STACK_SIZE ((configSTACK_DEPTH_TYPE) 512) #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 @@ -29,7 +25,7 @@ extern "C" { #define configSUPPORT_STATIC_ALLOCATION 0 #define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configTOTAL_HEAP_SIZE (128 * 1024) -#define configAPPLICATION_ALLOCATED_HEAP 4 +#define configAPPLICATION_ALLOCATED_HEAP 0 #define configCHECK_FOR_STACK_OVERFLOW 0 #define configUSE_MALLOC_FAILED_HOOK 0 #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 @@ -71,7 +67,3 @@ extern "C" { #define INCLUDE_xTaskResumeFromISR 1 #define INCLUDE_xQueueGetMutexHolder 1 -#ifdef __cplusplus -} // extern "C" -#endif - diff --git a/main/lwipopts.h b/main/lwipopts.h index 71c85b2..b2b6e76 100644 --- a/main/lwipopts.h +++ b/main/lwipopts.h @@ -77,3 +77,16 @@ #define SLIP_DEBUG LWIP_DBG_OFF #define DHCP_DEBUG LWIP_DBG_OFF +#define TCPIP_THREAD_STACKSIZE 2048 +#define DEFAULT_THREAD_STACKSIZE 1024 +#define DEFAULT_RAW_RECVMBOX_SIZE 8 +#define TCPIP_MBOX_SIZE 8 + +#define DEFAULT_UDP_RECVMBOX_SIZE TCPIP_MBOX_SIZE +#define DEFAULT_TCP_RECVMBOX_SIZE TCPIP_MBOX_SIZE +#define DEFAULT_ACCEPTMBOX_SIZE TCPIP_MBOX_SIZE + +#define LWIP_TIMEVAL_PRIVATE 0 + +#define LWIP_TCPIP_CORE_LOCKING_INPUT 1 + diff --git a/main/main.cpp b/main/main.cpp index d9d5e56..ace9f01 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -31,7 +31,7 @@ int main() { // this should compile but not work lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - // xTaskCreate((TaskFunction_t) blink_task, "blink", 128, NULL, 1, NULL); - // vTaskStartScheduler(); + xTaskCreate((TaskFunction_t) blink_task, "blink", 128, NULL, 1, NULL); + vTaskStartScheduler(); } -- cgit v1.2.3 From 21bfc93676c56e2265f330170d319da2c480987d Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 9 May 2024 15:18:51 +0200 Subject: working FreeRTOS + lwIP blink/wifi connect example again --- main/init.cpp | 30 ++++++++++++++++++++++++++---- main/init.h | 35 ++++++++++++++++++++++++++++++++++- main/main.cpp | 27 ++++++++++++++++----------- 3 files changed, 76 insertions(+), 16 deletions(-) (limited to 'main') diff --git a/main/init.cpp b/main/init.cpp index 425f591..48f3774 100644 --- a/main/init.cpp +++ b/main/init.cpp @@ -1,9 +1,15 @@ #include "config.h" #include "init.h" +#include +#include +#include + #include #include +EventGroupHandle_t init_complete; + static void init_stdio() { stdio_init_all(); } @@ -20,13 +26,29 @@ static void init_wifi() { if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CYW43_AUTH_WPA2_AES_PSK, CONF_NET_CONN_TIMEOUT)) panic("cyw43_arch_wifi_connect failed\n"); - // TODO: announce hostname + // TODO: announce hostname(?) } void init() { + init_complete = xEventGroupCreate(); + + // used for debug `printf` and `panic` on errors init_stdio(); - init_cyw34(); - init_wifi(); - // TODO: initialize i2c + + // defer other initialization until the task scheduler is running (important) + xTaskCreate((TaskFunction_t) [](void*) { + init_cyw34(); + init_wifi(); + // TODO: initialize i2c + + xEventGroupSetBits(init_complete, 1); + + // delete self + vTaskDelete(NULL); + }, "init", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 4, NULL); +} + +void await_init() { + xEventGroupWaitBits(init_complete, 1, pdFALSE, pdFALSE, portMAX_DELAY); } diff --git a/main/init.h b/main/init.h index 1f931dc..97b2e20 100644 --- a/main/init.h +++ b/main/init.h @@ -1,5 +1,38 @@ #pragma once -/** @brief initialize all peripherals on the pico */ +#include +#include + +/** + * @brief init function complete event group handle + * + * This is required to make sure the main task waits until initialization is + * complete. Due to the combination of FreeRTOS + lwIP, the initialization + * should be done while the task scheduler is running. Specifically the + * cyw43_arch_init functions make the pico hang indefinitely when used while + * the task scheduler is not running. + * + * @note `init_complete` only utilizes LSB, so `uxBitsToWaitFor` should always + * be set to *1* + */ +extern EventGroupHandle_t init_complete; + +/** + * @brief initialize all peripherals on the pico + * + * This function only synchronously initializes the standard input/output (used + * for `printf` and `panic`), and queues all other types of initialization in + * the `init` task using FreeRTOS. + * + * @note Tasks dependent on the wifi being initialized should use the + * `init_complete` event group to wait for initialization to complete! + */ void init(); +/** + * @brief block task until all initialization is complete + * + * utility function, see above comments + */ +void await_init(); + diff --git a/main/main.cpp b/main/main.cpp index ace9f01..c97a808 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -7,11 +7,13 @@ #include "config.h" #include "init.h" -#include -#include -#include +// #include +// #include +// #include void blink_task() { + await_init(); // `blink_task` uses GPIO + while (true) { cyw43_arch_gpio_put(LED_PIN, 0); vTaskDelay(250 / portTICK_PERIOD_MS); @@ -20,18 +22,21 @@ void blink_task() { } } +void test_task() { + int i = 0; + while (true) { + // stdio is initialized synchronously, so no `await_init` is needed + printf("hello #%d...\n", ++i); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } +} + int main() { init(); - for (int i = 5; i > 0; i--) { - printf("starting in %d...\n", i); - sleep_ms(1000); - } - - // this should compile but not work - lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + xTaskCreate((TaskFunction_t) blink_task, "blink", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); + xTaskCreate((TaskFunction_t) test_task, "test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); - xTaskCreate((TaskFunction_t) blink_task, "blink", 128, NULL, 1, NULL); vTaskStartScheduler(); } -- cgit v1.2.3 From adc6e726f672aa7057992af54b286f7632b4fb07 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 9 May 2024 15:38:25 +0200 Subject: stop the c++ --- main/CMakeLists.txt | 4 ++-- main/init.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ main/init.cpp | 54 --------------------------------------------------- main/main.c | 42 ++++++++++++++++++++++++++++++++++++++++ main/main.cpp | 42 ---------------------------------------- 5 files changed, 100 insertions(+), 98 deletions(-) create mode 100644 main/init.c delete mode 100644 main/init.cpp create mode 100644 main/main.c delete mode 100644 main/main.cpp (limited to 'main') diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index b86c077..123d1b7 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -13,8 +13,8 @@ project(puzzlebox_main C CXX ASM) pico_sdk_init() add_executable(main - main.cpp - init.cpp + main.c + init.c ) pico_enable_stdio_usb(main 1) diff --git a/main/init.c b/main/init.c new file mode 100644 index 0000000..616cfea --- /dev/null +++ b/main/init.c @@ -0,0 +1,56 @@ +#include "config.h" +#include "init.h" + +#include +#include +#include + +#include +#include + +EventGroupHandle_t init_complete; + +static void init_stdio() { + stdio_init_all(); +} + +static void init_cyw34() { + if (cyw43_arch_init_with_country(CONF_NET_COUNTRY)) + panic("cyw43_arch_init_with_country failed\n"); +} + +static void init_wifi() { + // enable 'station' mode (connect to an access point instead of acting like one) + cyw43_arch_enable_sta_mode(); + + if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CYW43_AUTH_WPA2_AES_PSK, CONF_NET_CONN_TIMEOUT)) + panic("cyw43_arch_wifi_connect failed\n"); + + // TODO: announce hostname(?) +} + +static void async_init() { + init_cyw34(); + init_wifi(); + // TODO: initialize i2c + + xEventGroupSetBits(init_complete, 1); + + // delete self + vTaskDelete(NULL); +} + +void init() { + init_complete = xEventGroupCreate(); + + // used for debug `printf` and `panic` on errors + init_stdio(); + + // defer other initialization until the task scheduler is running (important) + xTaskCreate((TaskFunction_t) async_init, "init", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 4, NULL); +} + +void await_init() { + xEventGroupWaitBits(init_complete, 1, pdFALSE, pdFALSE, portMAX_DELAY); +} + diff --git a/main/init.cpp b/main/init.cpp deleted file mode 100644 index 48f3774..0000000 --- a/main/init.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "config.h" -#include "init.h" - -#include -#include -#include - -#include -#include - -EventGroupHandle_t init_complete; - -static void init_stdio() { - stdio_init_all(); -} - -static void init_cyw34() { - if (cyw43_arch_init_with_country(CONF_NET_COUNTRY)) - panic("cyw43_arch_init_with_country failed\n"); -} - -static void init_wifi() { - // enable 'station' mode (connect to an access point instead of acting like one) - cyw43_arch_enable_sta_mode(); - - if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CYW43_AUTH_WPA2_AES_PSK, CONF_NET_CONN_TIMEOUT)) - panic("cyw43_arch_wifi_connect failed\n"); - - // TODO: announce hostname(?) -} - -void init() { - init_complete = xEventGroupCreate(); - - // used for debug `printf` and `panic` on errors - init_stdio(); - - // defer other initialization until the task scheduler is running (important) - xTaskCreate((TaskFunction_t) [](void*) { - init_cyw34(); - init_wifi(); - // TODO: initialize i2c - - xEventGroupSetBits(init_complete, 1); - - // delete self - vTaskDelete(NULL); - }, "init", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 4, NULL); -} - -void await_init() { - xEventGroupWaitBits(init_complete, 1, pdFALSE, pdFALSE, portMAX_DELAY); -} - diff --git a/main/main.c b/main/main.c new file mode 100644 index 0000000..c97a808 --- /dev/null +++ b/main/main.c @@ -0,0 +1,42 @@ +#include +#include + +#include +#include + +#include "config.h" +#include "init.h" + +// #include +// #include +// #include + +void blink_task() { + await_init(); // `blink_task` uses GPIO + + while (true) { + cyw43_arch_gpio_put(LED_PIN, 0); + vTaskDelay(250 / portTICK_PERIOD_MS); + cyw43_arch_gpio_put(LED_PIN, 1); + vTaskDelay(250 / portTICK_PERIOD_MS); + } +} + +void test_task() { + int i = 0; + while (true) { + // stdio is initialized synchronously, so no `await_init` is needed + printf("hello #%d...\n", ++i); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } +} + +int main() { + init(); + + xTaskCreate((TaskFunction_t) blink_task, "blink", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); + xTaskCreate((TaskFunction_t) test_task, "test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); + + vTaskStartScheduler(); +} + diff --git a/main/main.cpp b/main/main.cpp deleted file mode 100644 index c97a808..0000000 --- a/main/main.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include - -#include -#include - -#include "config.h" -#include "init.h" - -// #include -// #include -// #include - -void blink_task() { - await_init(); // `blink_task` uses GPIO - - while (true) { - cyw43_arch_gpio_put(LED_PIN, 0); - vTaskDelay(250 / portTICK_PERIOD_MS); - cyw43_arch_gpio_put(LED_PIN, 1); - vTaskDelay(250 / portTICK_PERIOD_MS); - } -} - -void test_task() { - int i = 0; - while (true) { - // stdio is initialized synchronously, so no `await_init` is needed - printf("hello #%d...\n", ++i); - vTaskDelay(1000 / portTICK_PERIOD_MS); - } -} - -int main() { - init(); - - xTaskCreate((TaskFunction_t) blink_task, "blink", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); - xTaskCreate((TaskFunction_t) test_task, "test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); - - vTaskStartScheduler(); -} - -- cgit v1.2.3 From 9263beca5c84f5f136c913439fe0557f1469e120 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 9 May 2024 17:04:59 +0200 Subject: WIP TCP socket server --- main/CMakeLists.txt | 1 + main/init.c | 2 ++ main/main.c | 2 ++ main/sock.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ main/sock.h | 5 +++++ 5 files changed, 56 insertions(+) create mode 100644 main/sock.c create mode 100644 main/sock.h (limited to 'main') diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 123d1b7..7b8d567 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -15,6 +15,7 @@ pico_sdk_init() add_executable(main main.c init.c + sock.c ) pico_enable_stdio_usb(main 1) diff --git a/main/init.c b/main/init.c index 616cfea..014a5ad 100644 --- a/main/init.c +++ b/main/init.c @@ -26,6 +26,8 @@ static void init_wifi() { if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CYW43_AUTH_WPA2_AES_PSK, CONF_NET_CONN_TIMEOUT)) panic("cyw43_arch_wifi_connect failed\n"); + printf("connected to Wi-Fi\n"); + // TODO: announce hostname(?) } diff --git a/main/main.c b/main/main.c index c97a808..a0a09a0 100644 --- a/main/main.c +++ b/main/main.c @@ -6,6 +6,7 @@ #include "config.h" #include "init.h" +#include "sock.h" // #include // #include @@ -36,6 +37,7 @@ int main() { xTaskCreate((TaskFunction_t) blink_task, "blink", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); xTaskCreate((TaskFunction_t) test_task, "test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); + xTaskCreate((TaskFunction_t) serve_task, "serve", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); vTaskStartScheduler(); } diff --git a/main/sock.c b/main/sock.c new file mode 100644 index 0000000..f55be5b --- /dev/null +++ b/main/sock.c @@ -0,0 +1,46 @@ +#include + +#include +#include + +#include "init.h" + +#include "config.h" + +err_t recv_handler(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { + if (p == NULL) return ERR_VAL; + + printf("recv: %s\n", (char *) p->payload); + + tcp_recved(pcb, p->len); + pbuf_free(p); + return ERR_OK; +} + +err_t accept_handler(void *arg, struct tcp_pcb *pcb, err_t err) { + tcp_recv(pcb, recv_handler); + + return ERR_OK; +} + +void serve_task() { + await_init(); + + // TODO: why does this hang??? + // printf("starting lwip...\n"); + // lwip_init(); + + printf("starting server...\n"); + + struct tcp_pcb *pcb = tcp_new(); + tcp_bind(pcb, IP_ADDR_ANY, CONF_SRV_PORT); + pcb = tcp_listen(pcb); + + printf("listening on %s:%d\n", ip4addr_ntoa(netif_ip4_addr(netif_list)), CONF_SRV_PORT); + + // connection accept callback + tcp_accept(pcb, accept_handler); + + printf("server started!\n"); +} + diff --git a/main/sock.h b/main/sock.h new file mode 100644 index 0000000..66dc874 --- /dev/null +++ b/main/sock.h @@ -0,0 +1,5 @@ +#pragma once + +/** @brief start listening for TCP socket requests */ +void serve_task(); + -- cgit v1.2.3 From 8a53d06efd517908f88f697a250059200e882c06 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Fri, 10 May 2024 13:34:22 +0200 Subject: fix TCP socket server --- main/config.def.h | 3 ++- main/init.c | 4 ++-- main/init.h | 10 +++++----- main/main.c | 14 -------------- main/sock.c | 54 ++++++++++++++++++++++++++++++------------------------ main/sock.h | 2 +- 6 files changed, 40 insertions(+), 47 deletions(-) (limited to 'main') diff --git a/main/config.def.h b/main/config.def.h index c6852ef..7fcaed9 100644 --- a/main/config.def.h +++ b/main/config.def.h @@ -4,8 +4,9 @@ // wifi credentials #define CONF_NET_SSID "network name" #define CONF_NET_PASS "network password" +#define CONF_NET_AUTH CYW43_AUTH_WPA2_AES_PSK // max duration (milliseconds) for establishing wifi connection -#define CONF_NET_CONN_TIMEOUT 10000 +#define CONF_NET_CONN_TIMEOUT 10e3 #include #define CONF_NET_COUNTRY CYW43_COUNTRY_NETHERLANDS diff --git a/main/init.c b/main/init.c index 014a5ad..dcd3d54 100644 --- a/main/init.c +++ b/main/init.c @@ -23,7 +23,7 @@ static void init_wifi() { // enable 'station' mode (connect to an access point instead of acting like one) cyw43_arch_enable_sta_mode(); - if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CYW43_AUTH_WPA2_AES_PSK, CONF_NET_CONN_TIMEOUT)) + if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CONF_NET_AUTH, CONF_NET_CONN_TIMEOUT)) panic("cyw43_arch_wifi_connect failed\n"); printf("connected to Wi-Fi\n"); @@ -33,8 +33,8 @@ static void init_wifi() { static void async_init() { init_cyw34(); - init_wifi(); // TODO: initialize i2c + init_wifi(); xEventGroupSetBits(init_complete, 1); diff --git a/main/init.h b/main/init.h index 97b2e20..de9023c 100644 --- a/main/init.h +++ b/main/init.h @@ -4,7 +4,7 @@ #include /** - * @brief init function complete event group handle + * \brief init function complete event group handle * * This is required to make sure the main task waits until initialization is * complete. Due to the combination of FreeRTOS + lwIP, the initialization @@ -12,25 +12,25 @@ * cyw43_arch_init functions make the pico hang indefinitely when used while * the task scheduler is not running. * - * @note `init_complete` only utilizes LSB, so `uxBitsToWaitFor` should always + * \note `init_complete` only utilizes LSB, so `uxBitsToWaitFor` should always * be set to *1* */ extern EventGroupHandle_t init_complete; /** - * @brief initialize all peripherals on the pico + * \brief initialize all peripherals on the pico * * This function only synchronously initializes the standard input/output (used * for `printf` and `panic`), and queues all other types of initialization in * the `init` task using FreeRTOS. * - * @note Tasks dependent on the wifi being initialized should use the + * \note Tasks dependent on the wifi being initialized should use the * `init_complete` event group to wait for initialization to complete! */ void init(); /** - * @brief block task until all initialization is complete + * \brief block task until all initialization is complete * * utility function, see above comments */ diff --git a/main/main.c b/main/main.c index a0a09a0..73b6708 100644 --- a/main/main.c +++ b/main/main.c @@ -8,10 +8,6 @@ #include "init.h" #include "sock.h" -// #include -// #include -// #include - void blink_task() { await_init(); // `blink_task` uses GPIO @@ -23,20 +19,10 @@ void blink_task() { } } -void test_task() { - int i = 0; - while (true) { - // stdio is initialized synchronously, so no `await_init` is needed - printf("hello #%d...\n", ++i); - vTaskDelay(1000 / portTICK_PERIOD_MS); - } -} - int main() { init(); xTaskCreate((TaskFunction_t) blink_task, "blink", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); - xTaskCreate((TaskFunction_t) test_task, "test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); xTaskCreate((TaskFunction_t) serve_task, "serve", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); vTaskStartScheduler(); diff --git a/main/sock.c b/main/sock.c index f55be5b..7064de7 100644 --- a/main/sock.c +++ b/main/sock.c @@ -1,46 +1,52 @@ #include -#include -#include +#include +#include +#include #include "init.h" #include "config.h" -err_t recv_handler(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { - if (p == NULL) return ERR_VAL; +void recv_handler(struct netconn* conn, struct netbuf* buf) { + void *data; + uint16_t len; - printf("recv: %s\n", (char *) p->payload); + do { + netbuf_data(buf, &data, &len); + printf("got %d bytes!\n", len); + } while (netbuf_next(buf) >= 0); - tcp_recved(pcb, p->len); - pbuf_free(p); - return ERR_OK; + netbuf_delete(buf); } -err_t accept_handler(void *arg, struct tcp_pcb *pcb, err_t err) { - tcp_recv(pcb, recv_handler); +void accept_handler(struct netconn* conn) { + printf("new connection!\n"); - return ERR_OK; + struct netbuf* buf; + + while (netconn_recv(conn, &buf) == ERR_OK) + recv_handler(conn, buf); + + netconn_close(conn); + netconn_delete(conn); + + printf("connection closed!\n"); } void serve_task() { await_init(); - // TODO: why does this hang??? - // printf("starting lwip...\n"); - // lwip_init(); - printf("starting server...\n"); - - struct tcp_pcb *pcb = tcp_new(); - tcp_bind(pcb, IP_ADDR_ANY, CONF_SRV_PORT); - pcb = tcp_listen(pcb); + struct netconn* conn = netconn_new(NETCONN_TCP); + netconn_bind(conn, IP_ADDR_ANY, CONF_SRV_PORT); + netconn_listen(conn); printf("listening on %s:%d\n", ip4addr_ntoa(netif_ip4_addr(netif_list)), CONF_SRV_PORT); - - // connection accept callback - tcp_accept(pcb, accept_handler); - - printf("server started!\n"); + while (1) { + struct netconn* incoming; + if (netconn_accept(conn, &incoming) == ERR_OK) + accept_handler(incoming); + } } diff --git a/main/sock.h b/main/sock.h index 66dc874..dd7fc61 100644 --- a/main/sock.h +++ b/main/sock.h @@ -1,5 +1,5 @@ #pragma once -/** @brief start listening for TCP socket requests */ +/** \brief start listening for TCP socket requests */ void serve_task(); -- cgit v1.2.3 From 573643a1d3220830de47c810cb1a6be629ce7abd Mon Sep 17 00:00:00 2001 From: lonkaars Date: Fri, 10 May 2024 14:49:36 +0200 Subject: WIP protobuf hello world --- .gitignore | 3 ++- .gitmodules | 12 ++++++------ client/.gitignore | 1 + client/CMakeLists.txt | 14 ++++++++++++++ client/compile_commands.json | 1 + client/main.cpp | 25 +++++++++++++++++++++++++ client/makefile | 2 ++ lazy.mk | 20 ++++++++++++++++++++ lib/FreeRTOS-Kernel | 1 + lib/googletest | 1 + lib/pico-sdk | 1 + main/.gitignore | 2 -- main/lib | 1 + main/lib/FreeRTOS-Kernel | 1 - main/lib/pico-sdk | 1 - main/makefile | 19 +++---------------- proto/.gitignore | 1 + proto/include.cmake | 1 + proto/makefile | 7 +++++++ proto/puzbusv1.proto | 12 ++++++++++++ test/CMakeLists.txt | 2 +- test/lib | 1 + test/lib/googletest | 1 - 23 files changed, 101 insertions(+), 29 deletions(-) create mode 100644 client/.gitignore create mode 100644 client/CMakeLists.txt create mode 120000 client/compile_commands.json create mode 100644 client/main.cpp create mode 100644 client/makefile create mode 100644 lazy.mk create mode 160000 lib/FreeRTOS-Kernel create mode 160000 lib/googletest create mode 160000 lib/pico-sdk create mode 120000 main/lib delete mode 160000 main/lib/FreeRTOS-Kernel delete mode 160000 main/lib/pico-sdk create mode 100644 proto/.gitignore create mode 100644 proto/include.cmake create mode 100644 proto/makefile create mode 100644 proto/puzbusv1.proto create mode 120000 test/lib delete mode 160000 test/lib/googletest (limited to 'main') diff --git a/.gitignore b/.gitignore index 0902ca8..19dc4f4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build -.vscode/** \ No newline at end of file +.vscode/** +.cache diff --git a/.gitmodules b/.gitmodules index 58b768d..fc98963 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,15 +1,15 @@ -[submodule "main/lib/pico-sdk"] - path = main/lib/pico-sdk +[submodule "pico-sdk"] + path = lib/pico-sdk url = https://github.com/raspberrypi/pico-sdk branch = 1.5.1 shallow = true -[submodule "test/lib/googletest"] - path = test/lib/googletest +[submodule "googletest"] + path = lib/googletest url = https://github.com/google/googletest branch = v1.14.0 shallow = true -[submodule "main/lib/FreeRTOS-Kernel"] - path = main/lib/FreeRTOS-Kernel +[submodule "FreeRTOS-Kernel"] + path = lib/FreeRTOS-Kernel url = https://github.com/FreeRTOS/FreeRTOS-Kernel branch = V11.1.0 shallow = true diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 0000000..ba2906d --- /dev/null +++ b/client/.gitignore @@ -0,0 +1 @@ +main diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt new file mode 100644 index 0000000..9e433b1 --- /dev/null +++ b/client/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.29) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_EXPORT_COMPILE_COMMANDS 1) + +include(../proto/include.cmake) + +project(puzzlebox_client C CXX) + +add_executable(main + main.cpp + ) + diff --git a/client/compile_commands.json b/client/compile_commands.json new file mode 120000 index 0000000..25eb4b2 --- /dev/null +++ b/client/compile_commands.json @@ -0,0 +1 @@ +build/compile_commands.json \ No newline at end of file diff --git a/client/main.cpp b/client/main.cpp new file mode 100644 index 0000000..7a05049 --- /dev/null +++ b/client/main.cpp @@ -0,0 +1,25 @@ +#include +#include + +#include "puzbusv1.pb.h" + +int main() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + puzbus::I2CMsg test_msg; + + test_msg.set_address(0x39); + test_msg.set_data("Test message data!"); + + std::string output; + test_msg.SerializeToString(&output); + + printf("output[%lu]:\n", output.size()); + for (size_t i = 0; i < output.size(); i++) { + printf("%02x ", output[i]); + } + printf("\n"); + + return 0; +} + diff --git a/client/makefile b/client/makefile new file mode 100644 index 0000000..8352615 --- /dev/null +++ b/client/makefile @@ -0,0 +1,2 @@ +include ../lazy.mk + diff --git a/lazy.mk b/lazy.mk new file mode 100644 index 0000000..2620961 --- /dev/null +++ b/lazy.mk @@ -0,0 +1,20 @@ +# this file is for lazy people (loek) + +BUILD_DIR ?= build +TARGET ?= $(BUILD_DIR)/main + +.PHONY: FORCE + +all: FORCE $(TARGET) + +$(BUILD_DIR)/build.ninja: CMakeLists.txt + mkdir -p $(BUILD_DIR) + cmake -B $(BUILD_DIR) -G Ninja --fresh --log-level WARNING + +$(TARGET): $(BUILD_DIR)/build.ninja FORCE + ninja -C $(BUILD_DIR) +# ninja automatically builds in parallel, so is preferred + +clean: FORCE + $(RM) -r $(BUILD_DIR) + diff --git a/lib/FreeRTOS-Kernel b/lib/FreeRTOS-Kernel new file mode 160000 index 0000000..dbf7055 --- /dev/null +++ b/lib/FreeRTOS-Kernel @@ -0,0 +1 @@ +Subproject commit dbf70559b27d39c1fdb68dfb9a32140b6a6777a0 diff --git a/lib/googletest b/lib/googletest new file mode 160000 index 0000000..5197b1a --- /dev/null +++ b/lib/googletest @@ -0,0 +1 @@ +Subproject commit 5197b1a8e6a1ef9f214f4aa537b0be17cbf91946 diff --git a/lib/pico-sdk b/lib/pico-sdk new file mode 160000 index 0000000..6a7db34 --- /dev/null +++ b/lib/pico-sdk @@ -0,0 +1 @@ +Subproject commit 6a7db34ff63345a7badec79ebea3aaef1712f374 diff --git a/main/.gitignore b/main/.gitignore index 7c3ba25..0e56cf2 100644 --- a/main/.gitignore +++ b/main/.gitignore @@ -1,3 +1 @@ config.h -build -.cache diff --git a/main/lib b/main/lib new file mode 120000 index 0000000..dc598c5 --- /dev/null +++ b/main/lib @@ -0,0 +1 @@ +../lib \ No newline at end of file diff --git a/main/lib/FreeRTOS-Kernel b/main/lib/FreeRTOS-Kernel deleted file mode 160000 index dbf7055..0000000 --- a/main/lib/FreeRTOS-Kernel +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dbf70559b27d39c1fdb68dfb9a32140b6a6777a0 diff --git a/main/lib/pico-sdk b/main/lib/pico-sdk deleted file mode 160000 index 6a7db34..0000000 --- a/main/lib/pico-sdk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6a7db34ff63345a7badec79ebea3aaef1712f374 diff --git a/main/makefile b/main/makefile index 1986cd3..9df4f09 100644 --- a/main/makefile +++ b/main/makefile @@ -1,22 +1,9 @@ -# this file is for lazy people (loek) +TARGET = $(BUILD_DIR)/main.uf2 -.PHONY: FORCE +include ../lazy.mk -all: FORCE build/main.uf2 - -build/build.ninja: CMakeLists.txt - mkdir -p build - cmake -B build -G Ninja --fresh --log-level WARNING - -build/main.uf2: build/build.ninja FORCE - ninja -C build -# ninja automatically builds in parallel, so is preferred - -flash: build/main.uf2 FORCE +flash: $(TARGET) FORCE picotool load -fx $< # -f forces a reboot of the pico before flashing # -x resets the pico after flashing -clean: FORCE - $(RM) -r build - diff --git a/proto/.gitignore b/proto/.gitignore new file mode 100644 index 0000000..75feca5 --- /dev/null +++ b/proto/.gitignore @@ -0,0 +1 @@ +*.pb.* diff --git a/proto/include.cmake b/proto/include.cmake new file mode 100644 index 0000000..d5beaef --- /dev/null +++ b/proto/include.cmake @@ -0,0 +1 @@ +include_directories(${CMAKE_CURRENT_LIST_DIR}) diff --git a/proto/makefile b/proto/makefile new file mode 100644 index 0000000..3bc4ca4 --- /dev/null +++ b/proto/makefile @@ -0,0 +1,7 @@ +PROTOCARGS += --cpp_out . + +all: puzbusv1.pb.cc puzbusv1.pb.h + +%.pb.cc %.pb.h &: %.proto + protoc $(PROTOCARGS) $< + diff --git a/proto/puzbusv1.proto b/proto/puzbusv1.proto new file mode 100644 index 0000000..6b4fa52 --- /dev/null +++ b/proto/puzbusv1.proto @@ -0,0 +1,12 @@ +syntax = "proto2"; + +package puzbus; + +message I2CMsg { + // 32-bit is the smallest integer format supported by protobuf, even though + // we only need 7-10 bits for the I2C address. + required uint32 address = 1; + + optional bytes data = 2; +} + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a0bd099..a280a86 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -20,4 +20,4 @@ target_link_libraries(tests PRIVATE gtest_main) add_test( NAME tests COMMAND tests -) \ No newline at end of file +) diff --git a/test/lib b/test/lib new file mode 120000 index 0000000..dc598c5 --- /dev/null +++ b/test/lib @@ -0,0 +1 @@ +../lib \ No newline at end of file diff --git a/test/lib/googletest b/test/lib/googletest deleted file mode 160000 index 5197b1a..0000000 --- a/test/lib/googletest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5197b1a8e6a1ef9f214f4aa537b0be17cbf91946 -- cgit v1.2.3 From cddfbb715d6f4f9d022d383ab8737b6af57a1d6f Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sat, 18 May 2024 15:08:20 +0200 Subject: cmake build config for mpack --- .gitmodules | 5 +++++ lib/mpack | 1 + main/CMakeLists.txt | 2 ++ proto/.gitignore | 1 - proto/include.cmake | 12 ++++++++++++ proto/lib | 1 + proto/makefile | 7 ------- proto/puzbusv1.c | 13 +++++++++++++ proto/puzbusv1.h | 22 ++++++++++++++++++++++ proto/puzbusv1.proto | 12 ------------ 10 files changed, 56 insertions(+), 20 deletions(-) create mode 160000 lib/mpack delete mode 100644 proto/.gitignore create mode 120000 proto/lib delete mode 100644 proto/makefile create mode 100644 proto/puzbusv1.c create mode 100644 proto/puzbusv1.h delete mode 100644 proto/puzbusv1.proto (limited to 'main') diff --git a/.gitmodules b/.gitmodules index fc98963..1a813e0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,8 @@ url = https://github.com/FreeRTOS/FreeRTOS-Kernel branch = V11.1.0 shallow = true +[submodule "lib/mpack"] + path = lib/mpack + url = https://github.com/ludocode/mpack + branch = v1.1.1 + shallow = true diff --git a/lib/mpack b/lib/mpack new file mode 160000 index 0000000..79d3fcd --- /dev/null +++ b/lib/mpack @@ -0,0 +1 @@ +Subproject commit 79d3fcd3e04338b06e82d01a62f4aa98c7bad5f7 diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 7b8d567..cd90499 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -7,6 +7,7 @@ set(PICO_BOARD pico_w) include(lib/pico-sdk/pico_sdk_init.cmake) include(lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake) +include(../proto/include.cmake) project(puzzlebox_main C CXX ASM) @@ -30,5 +31,6 @@ target_link_libraries(main pico_stdlib FreeRTOS-Kernel FreeRTOS-Kernel-Heap4 + mpack ) diff --git a/proto/.gitignore b/proto/.gitignore deleted file mode 100644 index 75feca5..0000000 --- a/proto/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pb.* diff --git a/proto/include.cmake b/proto/include.cmake index d5beaef..c8a90b6 100644 --- a/proto/include.cmake +++ b/proto/include.cmake @@ -1 +1,13 @@ include_directories(${CMAKE_CURRENT_LIST_DIR}) + +# mpack +include_directories(${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack) +add_library(mpack STATIC + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-common.c + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-expect.c + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-node.c + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-platform.c + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-reader.c + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-writer.c + ) + diff --git a/proto/lib b/proto/lib new file mode 120000 index 0000000..dc598c5 --- /dev/null +++ b/proto/lib @@ -0,0 +1 @@ +../lib \ No newline at end of file diff --git a/proto/makefile b/proto/makefile deleted file mode 100644 index 3bc4ca4..0000000 --- a/proto/makefile +++ /dev/null @@ -1,7 +0,0 @@ -PROTOCARGS += --cpp_out . - -all: puzbusv1.pb.cc puzbusv1.pb.h - -%.pb.cc %.pb.h &: %.proto - protoc $(PROTOCARGS) $< - diff --git a/proto/puzbusv1.c b/proto/puzbusv1.c new file mode 100644 index 0000000..9d1335e --- /dev/null +++ b/proto/puzbusv1.c @@ -0,0 +1,13 @@ +#include + +#include "puzbusv1.h" + +int pb_read(struct pb_msg* target, char* buf, size_t buf_sz) { + mpack_reader_t reader; + + return 0; +} + +void pb_free(struct pb_msg* msg); + + diff --git a/proto/puzbusv1.h b/proto/puzbusv1.h new file mode 100644 index 0000000..071c887 --- /dev/null +++ b/proto/puzbusv1.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct pb_msg { + uint16_t addr; + char* data; + size_t length; +}; + +int pb_read(struct pb_msg* target, char* buf, size_t buf_sz); +void pb_free(struct pb_msg* msg); + +#ifdef __cplusplus +} +#endif + diff --git a/proto/puzbusv1.proto b/proto/puzbusv1.proto deleted file mode 100644 index 6b4fa52..0000000 --- a/proto/puzbusv1.proto +++ /dev/null @@ -1,12 +0,0 @@ -syntax = "proto2"; - -package puzbus; - -message I2CMsg { - // 32-bit is the smallest integer format supported by protobuf, even though - // we only need 7-10 bits for the I2C address. - required uint32 address = 1; - - optional bytes data = 2; -} - -- cgit v1.2.3 From 1152ec32b6086c153dc41da59c9c451aa4465995 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sat, 18 May 2024 20:11:44 +0200 Subject: WIP send/receive w/ msgpack --- client/CMakeLists.txt | 10 +++++++-- client/lib | 1 + client/main.cpp | 61 +++++++++++++++++++++++++++++++++++++-------------- main/sock.c | 8 +++---- main/sock.h | 6 +++++ proto/include.cmake | 3 +++ proto/puzbusv1.c | 21 +++++++++++++++++- proto/puzbusv1.h | 2 +- 8 files changed, 88 insertions(+), 24 deletions(-) create mode 120000 client/lib (limited to 'main') diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 9e433b1..bcef4c0 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -4,11 +4,17 @@ set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 17) set(CMAKE_EXPORT_COMPILE_COMMANDS 1) -include(../proto/include.cmake) - project(puzzlebox_client C CXX) +include(../proto/include.cmake) + add_executable(main main.cpp ) +target_link_libraries(main + puzbus + mpack + ) + + diff --git a/client/lib b/client/lib new file mode 120000 index 0000000..dc598c5 --- /dev/null +++ b/client/lib @@ -0,0 +1 @@ +../lib \ No newline at end of file diff --git a/client/main.cpp b/client/main.cpp index 7a05049..30d7045 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -1,25 +1,54 @@ #include -#include - -#include "puzbusv1.pb.h" - -int main() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - puzbus::I2CMsg test_msg; +#include +#include +#include + +#include "puzbusv1.h" + +int send_message() { + const char* data = "Test message data!"; + struct pb_msg output = { + .addr = 0x39, + .data = (char*) data, + .length = strlen(data), + }; + + char* packed; + size_t size; + if (!pb_write(&output, &packed, &size)) { + printf("error writing!\n"); + return 1; + } - test_msg.set_address(0x39); - test_msg.set_data("Test message data!"); + fwrite(packed, sizeof(packed[0]), size, stdout); + fflush(stdout); - std::string output; - test_msg.SerializeToString(&output); + return 0; +} - printf("output[%lu]:\n", output.size()); - for (size_t i = 0; i < output.size(); i++) { - printf("%02x ", output[i]); +int read_message() { + freopen(NULL, "rb", stdin); // allow binary on stdin + struct pb_msg input; + + char buf[8]; // extremely small buffer to test chunked message parsing + size_t bytes = 0; + while ((bytes = fread(buf, sizeof(buf[0]), sizeof(buf), stdin)) > 0) { + if (!pb_read(&input, buf, bytes)) continue; + + printf("address: 0x%02x\n", input.addr); + printf("data: \"%.*s\"\n", input.length, input.data); + free(input.data); + return 0; } - printf("\n"); + return 1; +} + +int main() { + if (!isatty(fileno(stdout))) return send_message(); + if (!isatty(fileno(stdin))) return read_message(); + + printf("please pipe some data in or out to use this program\n"); return 0; } diff --git a/main/sock.c b/main/sock.c index 7064de7..dac62af 100644 --- a/main/sock.c +++ b/main/sock.c @@ -5,9 +5,10 @@ #include #include "init.h" - #include "config.h" +struct netconn* current_connection = NULL; + void recv_handler(struct netconn* conn, struct netbuf* buf) { void *data; uint16_t len; @@ -21,17 +22,16 @@ void recv_handler(struct netconn* conn, struct netbuf* buf) { } void accept_handler(struct netconn* conn) { - printf("new connection!\n"); + current_connection = conn; struct netbuf* buf; - while (netconn_recv(conn, &buf) == ERR_OK) recv_handler(conn, buf); netconn_close(conn); netconn_delete(conn); - printf("connection closed!\n"); + current_connection = NULL; } void serve_task() { diff --git a/main/sock.h b/main/sock.h index dd7fc61..2a73418 100644 --- a/main/sock.h +++ b/main/sock.h @@ -1,5 +1,11 @@ #pragma once +#include +#include + /** \brief start listening for TCP socket requests */ void serve_task(); +void i2c_send(uint16_t addr, char* data, size_t data_size); +void i2c_recv(uint16_t addr, char* data, size_t data_size); + diff --git a/proto/include.cmake b/proto/include.cmake index c8a90b6..ac1305e 100644 --- a/proto/include.cmake +++ b/proto/include.cmake @@ -1,4 +1,7 @@ include_directories(${CMAKE_CURRENT_LIST_DIR}) +add_library(puzbus STATIC + ${CMAKE_CURRENT_LIST_DIR}/puzbusv1.c + ) # mpack include_directories(${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack) diff --git a/proto/puzbusv1.c b/proto/puzbusv1.c index 9d1335e..3ff7c63 100644 --- a/proto/puzbusv1.c +++ b/proto/puzbusv1.c @@ -1,13 +1,32 @@ #include +#include #include "puzbusv1.h" int pb_read(struct pb_msg* target, char* buf, size_t buf_sz) { mpack_reader_t reader; + printf("read %lu bytes...\n", buf_sz); + + mpack_reader_init_data(&reader, buf, buf_sz); + + uint16_t address = mpack_expect_u16(&reader); + char data_buf[80]; + size_t data_size = mpack_expect_bin_buf(&reader, data_buf, sizeof(data_buf)); + + printf("0x%02x\n", address); + printf("\"%.*s\"\n", data_size, data_buf); return 0; } -void pb_free(struct pb_msg* msg); +int pb_write(struct pb_msg* target, char** buf, size_t* buf_sz) { + mpack_writer_t writer; + mpack_writer_init_growable(&writer, buf, buf_sz); + mpack_write_u16(&writer, target->addr); + mpack_write_bin(&writer, target->data, target->length); + + // finish writing + return mpack_writer_destroy(&writer) == mpack_ok; +} diff --git a/proto/puzbusv1.h b/proto/puzbusv1.h index 071c887..116dbf9 100644 --- a/proto/puzbusv1.h +++ b/proto/puzbusv1.h @@ -14,7 +14,7 @@ struct pb_msg { }; int pb_read(struct pb_msg* target, char* buf, size_t buf_sz); -void pb_free(struct pb_msg* msg); +int pb_write(struct pb_msg* target, char** buf, size_t* buf_sz); #ifdef __cplusplus } -- cgit v1.2.3 From 56440df6b9810dbbc4b33171030970fa2fbe1ca1 Mon Sep 17 00:00:00 2001 From: ThomasintAnker Date: Sat, 18 May 2024 20:48:50 +0200 Subject: Base i2c master functions --- main/CMakeLists.txt | 2 ++ main/i2c.c | 29 +++++++++++++++++++++++++++++ main/i2c.h | 36 ++++++++++++++++++++++++++++++++++++ main/init.c | 3 ++- 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 main/i2c.c create mode 100644 main/i2c.h (limited to 'main') diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index cd90499..88abf60 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable(main main.c init.c sock.c + i2c.c ) pico_enable_stdio_usb(main 1) @@ -29,6 +30,7 @@ target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR}) target_link_libraries(main pico_cyw43_arch_lwip_sys_freertos pico_stdlib + hardware_i2c FreeRTOS-Kernel FreeRTOS-Kernel-Heap4 mpack diff --git a/main/i2c.c b/main/i2c.c new file mode 100644 index 0000000..7ab1d14 --- /dev/null +++ b/main/i2c.c @@ -0,0 +1,29 @@ +#include "i2c.h" + +#include +#include +#include +#include +#include + +void init_i2c() { + stdio_init_all(); + i2c_init(i2c_default, 100 * 1000); + + // Initialize I2C pins - sda(16), scl(17) + gpio_set_function(SDA_PIN, GPIO_FUNC_I2C); + gpio_set_function(SCL_PIN, GPIO_FUNC_I2C); + + gpio_pull_up(SDA_PIN); + gpio_pull_up(SCL_PIN); +} + +int read_i2c(uint8_t addr, uint8_t *output, size_t len) { + // false - finished with bus + return i2c_read_blocking (i2c_default, addr, output, len, false); +} + +int write_i2c(uint8_t addr, uint8_t *input, size_t len) { + // true to keep master control of bus + return i2c_write_blocking (i2c_default, addr, input, len, true); +} diff --git a/main/i2c.h b/main/i2c.h new file mode 100644 index 0000000..d12bca1 --- /dev/null +++ b/main/i2c.h @@ -0,0 +1,36 @@ +#pragma once +// https://github.com/raspberrypi/pico-examples/tree/master/i2c + +#include +#include + +#define SDA_PIN 16 +#define SCL_PIN 17 + +/** + * \brief initialize all required gpio for i2c usage on the pico + * + * This functions only initializes the standard gpio required to start i2c + * communications. + * + * \note Tasks shouldn't depend on any other module in the main controller + */ +void init_i2c(); + +/** + * \brief read data from addr with length len from i2c bus. + * + * This functions reads data from a specific address on the i2c bus, + * the output var will hold the data which was read from said address with + * length len. + */ +int read_i2c(uint8_t addr, uint8_t *output, size_t len); + +/** + * \brief write data to addr with length len from i2c bus. + * + * This functions writes data to a specific address on the i2c bus, + * the input var holds the data which will be written to the given + * address with length len. + */ +int write_i2c(uint8_t addr, uint8_t *input, size_t len); diff --git a/main/init.c b/main/init.c index dcd3d54..f336ad0 100644 --- a/main/init.c +++ b/main/init.c @@ -1,5 +1,6 @@ #include "config.h" #include "init.h" +#include "i2c.h" #include #include @@ -33,7 +34,7 @@ static void init_wifi() { static void async_init() { init_cyw34(); - // TODO: initialize i2c + init_i2c(); init_wifi(); xEventGroupSetBits(init_complete, 1); -- cgit v1.2.3 From 2d3ba07806517f0d27b118df761675a05ab98fc7 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sun, 19 May 2024 15:10:46 +0200 Subject: add puzzle bus serializer to main controller application --- main/CMakeLists.txt | 1 + main/sock.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 5 deletions(-) (limited to 'main') diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index cd90499..90ca8e3 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -31,6 +31,7 @@ target_link_libraries(main pico_stdlib FreeRTOS-Kernel FreeRTOS-Kernel-Heap4 + puzbus mpack ) diff --git a/main/sock.c b/main/sock.c index dac62af..705e2eb 100644 --- a/main/sock.c +++ b/main/sock.c @@ -3,19 +3,61 @@ #include #include #include +#include #include "init.h" #include "config.h" +#include "puzbusv1.h" +#include "sock.h" struct netconn* current_connection = NULL; +struct pb_msg recv_msg; -void recv_handler(struct netconn* conn, struct netbuf* buf) { - void *data; - uint16_t len; +void i2c_send(uint16_t addr, char* data, size_t data_size) { + if (current_connection == NULL) return; + + struct pb_msg send_msg = { + .addr = addr, + .data = data, + .length = data_size, + }; + + char* buf; + size_t buf_sz; + + if (!pb_write(&send_msg, &buf, &buf_sz)) return; + + // NOTE: netconn does return an error code, but the data needs to be freed + // whether netconn throws an error or not, so it remains unused + netconn_write(current_connection, buf, buf_sz, NETCONN_COPY); + + free(buf); +} +void i2c_recv(uint16_t addr, char* data, size_t data_size) { + printf("address: 0x%02x\n", addr); + printf("data: \"%.*s\"\n", data_size, data); + + // send message back + char reply[] = "Test message back!"; + i2c_send(0x69, reply, strlen(reply)); + + // TODO: this function should forward the recieved message onto the puzzle + // bus instead of printing/replying +} + +void recv_handler(struct netconn* conn, struct netbuf* buf) { do { - netbuf_data(buf, &data, &len); - printf("got %d bytes!\n", len); + char* data; + uint16_t len; + netbuf_data(buf, (void**)&data, &len); + + // continue early if more data is needed to complete message + if (!pb_read(&recv_msg, data, len)) continue; + + // forward received message to puzzle bus + i2c_recv(recv_msg.addr, recv_msg.data, recv_msg.length); + free(recv_msg.data); } while (netbuf_next(buf) >= 0); netbuf_delete(buf); -- cgit v1.2.3 From 68a5c65f9b0e1df30e9cef490d9b218b2f21f90d Mon Sep 17 00:00:00 2001 From: lonkaars Date: Tue, 21 May 2024 10:30:06 +0200 Subject: clean up puzbusv1 API --- client/sock.cpp | 12 ++++++------ client/sock.h | 13 ++++++------- main/sock.c | 10 ++++++---- main/sock.h | 4 ++-- proto/puzbusv1.c | 33 +++++++++++---------------------- proto/puzbusv1.h | 14 ++++++++------ 6 files changed, 39 insertions(+), 47 deletions(-) (limited to 'main') diff --git a/client/sock.cpp b/client/sock.cpp index cc18a69..f967f64 100644 --- a/client/sock.cpp +++ b/client/sock.cpp @@ -18,7 +18,7 @@ using std::logic_error; using std::thread; PBSocket::PBSocket() { } -PBSocket::PBSocket(char* addr, uint16_t port) : PBSocket() { +PBSocket::PBSocket(const char * addr, uint16_t port) : PBSocket() { set_server(addr, port); } @@ -32,7 +32,7 @@ PBSocket::~PBSocket() { sock_close(); } -void PBSocket::set_server(char* addr, uint16_t port) { +void PBSocket::set_server(const char * addr, uint16_t port) { _addr = addr; _port = port; } @@ -67,7 +67,7 @@ void PBSocket::sock_close() { _fd = -1; } -void PBSocket::send(char* buf, size_t buf_sz) { +void PBSocket::send(const char * buf, size_t buf_sz) { write(_fd, buf, buf_sz); } @@ -105,10 +105,10 @@ void PBSocket::sock_task() { sock_close(); } -void i2c_send(uint16_t addr, char* data, size_t data_size) { +void i2c_send(uint16_t addr, const char * data, size_t data_size) { struct pb_msg msg = { .addr = addr, - .data = data, + .data = (char *) data, .length = data_size, }; @@ -119,7 +119,7 @@ void i2c_send(uint16_t addr, char* data, size_t data_size) { sock->send(packed, size); } -void i2c_recv(uint16_t addr, char* data, size_t data_size) { +void i2c_recv(uint16_t addr, const char * data, size_t data_size) { rl_printf("[0x%02x]: %.*s\n", addr, data_size, data); } diff --git a/client/sock.h b/client/sock.h index 818ea72..42eba3b 100644 --- a/client/sock.h +++ b/client/sock.h @@ -6,14 +6,14 @@ class PBSocket { public: PBSocket(); - PBSocket(char* addr, uint16_t port); + PBSocket(const char * addr, uint16_t port); virtual ~PBSocket(); - void set_server(char* addr, uint16_t port); + void set_server(const char * addr, uint16_t port); void sock_connect(); - void send(char* buf, size_t buf_sz); + void send(const char * buf, size_t buf_sz); private: void sock_task(); @@ -21,15 +21,14 @@ private: std::thread* _thread = nullptr; - char* _addr = NULL; + const char * _addr = NULL; uint16_t _port = 0; int _fd = -1; - }; extern PBSocket* sock; -void i2c_send(uint16_t addr, char* data, size_t data_size); -void i2c_recv(uint16_t addr, char* data, size_t data_size); +void i2c_send(uint16_t addr, const char * data, size_t data_size); +void i2c_recv(uint16_t addr, const char * data, size_t data_size); diff --git a/main/sock.c b/main/sock.c index 705e2eb..4f50981 100644 --- a/main/sock.c +++ b/main/sock.c @@ -13,16 +13,16 @@ struct netconn* current_connection = NULL; struct pb_msg recv_msg; -void i2c_send(uint16_t addr, char* data, size_t data_size) { +void i2c_send(uint16_t addr, const char * data, size_t data_size) { if (current_connection == NULL) return; struct pb_msg send_msg = { .addr = addr, - .data = data, + .data = (char *) data, .length = data_size, }; - char* buf; + char * buf; size_t buf_sz; if (!pb_write(&send_msg, &buf, &buf_sz)) return; @@ -34,7 +34,7 @@ void i2c_send(uint16_t addr, char* data, size_t data_size) { free(buf); } -void i2c_recv(uint16_t addr, char* data, size_t data_size) { +void i2c_recv(uint16_t addr, const char * data, size_t data_size) { printf("address: 0x%02x\n", addr); printf("data: \"%.*s\"\n", data_size, data); @@ -47,6 +47,8 @@ void i2c_recv(uint16_t addr, char* data, size_t data_size) { } void recv_handler(struct netconn* conn, struct netbuf* buf) { + pb_read_reset(&recv_msg); + do { char* data; uint16_t len; diff --git a/main/sock.h b/main/sock.h index 2a73418..f2db35d 100644 --- a/main/sock.h +++ b/main/sock.h @@ -6,6 +6,6 @@ /** \brief start listening for TCP socket requests */ void serve_task(); -void i2c_send(uint16_t addr, char* data, size_t data_size); -void i2c_recv(uint16_t addr, char* data, size_t data_size); +void i2c_send(uint16_t addr, const char * data, size_t data_size); +void i2c_recv(uint16_t addr, const char * data, size_t data_size); diff --git a/proto/puzbusv1.c b/proto/puzbusv1.c index 3be4939..73deda5 100644 --- a/proto/puzbusv1.c +++ b/proto/puzbusv1.c @@ -7,24 +7,13 @@ #include "puzbusv1.h" -/** - * \brief Remaining bytes to be read to target->data - * - * This is the only variable that needs to persist between buffer blocks. It is - * declared in the global scope to allow resetting using the \c pb_read_reset() - * function. - * - * \note \p rdata may be reset by calling \c pb_read_reset() - */ -static size_t rdata = 0; - -int pb_read(struct pb_msg* target, char* buf, size_t buf_sz) { +int pb_read(struct pb_msg * target, const char * buf, size_t buf_sz) { // a new reader is used per buffer block passed to this function mpack_reader_t reader; mpack_reader_init_data(&reader, buf, buf_sz); // at start of message - if (rdata == 0) { + if (target->_rdata == 0) { // NOTE: The entire start of a message needs to be readable from the buffer // at this point. When target->addr can be read and target->length is past // the end of the current buffer block, this function will crash and burn. @@ -34,26 +23,26 @@ int pb_read(struct pb_msg* target, char* buf, size_t buf_sz) { if (buf_sz < 4) return -1; target->addr = mpack_expect_u16(&reader); - target->length = rdata = mpack_expect_bin(&reader); - target->data = (char*) malloc(target->length); + target->length = target->_rdata = mpack_expect_bin(&reader); + target->data = (char *) malloc(target->length); } // continue reading chunks of target->data until the amount of bytes // specified in target->length - size_t to_read = MIN(mpack_reader_remaining(&reader, NULL), rdata); - char* data = target->data + target->length - rdata; // 'ol pointer arithmetic + size_t to_read = MIN(mpack_reader_remaining(&reader, NULL), target->_rdata); + char * data = target->data + target->length - target->_rdata; mpack_read_bytes(&reader, data, to_read); - rdata -= to_read; + target->_rdata -= to_read; // if rdata = 0, the message was completely read - return rdata; + return target->_rdata; } -void pb_read_reset() { - rdata = 0; +void pb_read_reset(struct pb_msg * target) { + target->_rdata = 0; } -bool pb_write(struct pb_msg* target, char** buf, size_t* buf_sz) { +bool pb_write(const struct pb_msg * target, char ** buf, size_t * buf_sz) { mpack_writer_t writer; mpack_writer_init_growable(&writer, buf, buf_sz); diff --git a/proto/puzbusv1.h b/proto/puzbusv1.h index 95130c9..0985b2b 100644 --- a/proto/puzbusv1.h +++ b/proto/puzbusv1.h @@ -7,10 +7,12 @@ extern "C" { #endif +/** \brief Puzzle bus message (v1) */ struct pb_msg { - uint16_t addr; - char* data; - size_t length; + uint16_t addr; //!< I^2^C address + char * data; //!< message content + size_t length; //!< message size + size_t _rdata; //!< \private remaining bytes to read until message is complete }; /** @@ -32,7 +34,7 @@ struct pb_msg { * the message is not fully parsed. This variable must be `free()`d by the * caller after each complete message to prevent memory leaks. */ -int pb_read(struct pb_msg* target, char* buf, size_t buf_sz); +int pb_read(struct pb_msg * target, const char * buf, size_t buf_sz); /** * \brief reset the remaining message data counter @@ -42,7 +44,7 @@ int pb_read(struct pb_msg* target, char* buf, size_t buf_sz); * before reading a TCP frame's data to mitigate any synchronization issues * arising from earlier corrupt or otherwise malformed messages. */ -void pb_read_reset(); +void pb_read_reset(struct pb_msg * target); /** * \brief Allocate and write a msgpack-formatted message to \p buf @@ -60,7 +62,7 @@ void pb_read_reset(); * * \note the pointer stored in \p buf must be `free()`d by the caller afterwards */ -bool pb_write(struct pb_msg* target, char** buf, size_t* buf_sz); +bool pb_write(const struct pb_msg * target, char ** buf, size_t * buf_sz); #ifdef __cplusplus } -- cgit v1.2.3 From 142772eb21060b66678ced9861d7718b7d2a215d Mon Sep 17 00:00:00 2001 From: ThomasintAnker Date: Tue, 21 May 2024 13:19:47 +0200 Subject: wip --- main/i2c.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- main/i2c.h | 8 +++++++- main/main.c | 2 ++ 3 files changed, 70 insertions(+), 2 deletions(-) (limited to 'main') diff --git a/main/i2c.c b/main/i2c.c index 7ab1d14..3ecc2ee 100644 --- a/main/i2c.c +++ b/main/i2c.c @@ -8,7 +8,7 @@ void init_i2c() { stdio_init_all(); - i2c_init(i2c_default, 100 * 1000); + i2c_init(i2c_default, 100 * 1000); // currently at 100kHz // Initialize I2C pins - sda(16), scl(17) gpio_set_function(SDA_PIN, GPIO_FUNC_I2C); @@ -27,3 +27,63 @@ int write_i2c(uint8_t addr, uint8_t *input, size_t len) { // true to keep master control of bus return i2c_write_blocking (i2c_default, addr, input, len, true); } + +bool reserved_addr(uint8_t addr) { + return (addr & 0x78) == 0 || (addr & 0x78) == 0x78; +} + +void init_addr_array(uint8_t array[]) { + for(int i = 0; i < MAX_SLAVES; i++){ + array[i] = 0x00; + } +} + +uint8_t scan_bus(uint8_t array[]) { + int ret; + int i = 0; + uint8_t rxdata; + + for(int addr = 0; addr < (1<<7); addr++) { + // ignore reserved addresses + // These are any addresses of the form 000 0xxx or 111 1xxx + if( reserved_addr(addr) ){ + ret = PICO_ERROR_GENERIC; + }else{ + ret = i2c_read_blocking(i2c_default, addr, &rxdata, 1, false); + } + + // if acknowledged -> ret == number of bytes sent + if(ret > 0){ + array[i] = addr; + i++; + } + } + + return array; +} + +void bus_task() { + // scan bus for slaves + // send updates at regular intervals + + int i = 0; + uint8_t *found[MAX_SLAVES]; + init_addr_array(&found); + + while(1) { + scan_bus(&found); + + for(int i = 0; i < MAX_SLAVES; i++){ + if( found[i] == 0x00 ) + break; + + // send data to found slave address + write_i2c(found[i], 0x01, 1); + + write_i2c(found[i], 0x00, 1); + // request update from slave addr at found[i] + //write_i2c(); + } + } + +} diff --git a/main/i2c.h b/main/i2c.h index d12bca1..405ae1f 100644 --- a/main/i2c.h +++ b/main/i2c.h @@ -6,6 +6,7 @@ #define SDA_PIN 16 #define SCL_PIN 17 +#define MAX_SLAVES 10 /** * \brief initialize all required gpio for i2c usage on the pico @@ -28,9 +29,14 @@ int read_i2c(uint8_t addr, uint8_t *output, size_t len); /** * \brief write data to addr with length len from i2c bus. - * + * \param addr + * \param input + * \param len * This functions writes data to a specific address on the i2c bus, * the input var holds the data which will be written to the given * address with length len. */ int write_i2c(uint8_t addr, uint8_t *input, size_t len); + +/** \brief looking for slave addresses and requesting updates */ +void bus_task(); diff --git a/main/main.c b/main/main.c index 73b6708..b38030f 100644 --- a/main/main.c +++ b/main/main.c @@ -7,6 +7,7 @@ #include "config.h" #include "init.h" #include "sock.h" +#include "i2c.h" void blink_task() { await_init(); // `blink_task` uses GPIO @@ -24,6 +25,7 @@ int main() { xTaskCreate((TaskFunction_t) blink_task, "blink", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); xTaskCreate((TaskFunction_t) serve_task, "serve", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); + xTaskCreate((TaskFunction_t) bus_task, "bus", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); vTaskStartScheduler(); } -- cgit v1.2.3 From 5e7481e9170c1334d74a57e84640e89a40cf74c3 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Tue, 21 May 2024 13:34:26 +0200 Subject: fix brokey --- main/i2c.c | 116 +++++++++++++++++++++++++++++++----------------------------- main/init.c | 4 +-- 2 files changed, 61 insertions(+), 59 deletions(-) (limited to 'main') diff --git a/main/i2c.c b/main/i2c.c index 3ecc2ee..cbf6938 100644 --- a/main/i2c.c +++ b/main/i2c.c @@ -7,83 +7,85 @@ #include void init_i2c() { - stdio_init_all(); + stdio_init_all(); i2c_init(i2c_default, 100 * 1000); // currently at 100kHz // Initialize I2C pins - sda(16), scl(17) - gpio_set_function(SDA_PIN, GPIO_FUNC_I2C); - gpio_set_function(SCL_PIN, GPIO_FUNC_I2C); + gpio_set_function(SDA_PIN, GPIO_FUNC_I2C); + gpio_set_function(SCL_PIN, GPIO_FUNC_I2C); - gpio_pull_up(SDA_PIN); - gpio_pull_up(SCL_PIN); + gpio_pull_up(SDA_PIN); + gpio_pull_up(SCL_PIN); } int read_i2c(uint8_t addr, uint8_t *output, size_t len) { - // false - finished with bus - return i2c_read_blocking (i2c_default, addr, output, len, false); + // false - finished with bus + return i2c_read_blocking (i2c_default, addr, output, len, false); } int write_i2c(uint8_t addr, uint8_t *input, size_t len) { - // true to keep master control of bus - return i2c_write_blocking (i2c_default, addr, input, len, true); + // true to keep master control of bus + return i2c_write_blocking (i2c_default, addr, input, len, true); } bool reserved_addr(uint8_t addr) { - return (addr & 0x78) == 0 || (addr & 0x78) == 0x78; + return (addr & 0x78) == 0 || (addr & 0x78) == 0x78; } void init_addr_array(uint8_t array[]) { - for(int i = 0; i < MAX_SLAVES; i++){ - array[i] = 0x00; - } + for(int i = 0; i < MAX_SLAVES; i++){ + array[i] = 0x00; + } } -uint8_t scan_bus(uint8_t array[]) { - int ret; - int i = 0; - uint8_t rxdata; - - for(int addr = 0; addr < (1<<7); addr++) { - // ignore reserved addresses - // These are any addresses of the form 000 0xxx or 111 1xxx - if( reserved_addr(addr) ){ - ret = PICO_ERROR_GENERIC; - }else{ - ret = i2c_read_blocking(i2c_default, addr, &rxdata, 1, false); - } - - // if acknowledged -> ret == number of bytes sent - if(ret > 0){ - array[i] = addr; - i++; - } - } - - return array; +uint8_t* scan_bus(uint8_t* array) { + int ret; + int i = 0; + uint8_t rxdata; + + for(int addr = 0; addr < (1<<7); addr++) { + // ignore reserved addresses + // These are any addresses of the form 000 0xxx or 111 1xxx + if( reserved_addr(addr) ){ + ret = PICO_ERROR_GENERIC; + }else{ + ret = i2c_read_blocking(i2c_default, addr, &rxdata, 1, false); + } + + // if acknowledged -> ret == number of bytes sent + if(ret > 0){ + array[i] = addr; + i++; + } + } + + return array; } void bus_task() { - // scan bus for slaves - // send updates at regular intervals - - int i = 0; - uint8_t *found[MAX_SLAVES]; - init_addr_array(&found); - - while(1) { - scan_bus(&found); - - for(int i = 0; i < MAX_SLAVES; i++){ - if( found[i] == 0x00 ) - break; - - // send data to found slave address - write_i2c(found[i], 0x01, 1); - - write_i2c(found[i], 0x00, 1); - // request update from slave addr at found[i] - //write_i2c(); - } - } + // scan bus for slaves + // send updates at regular intervals + + int i = 0; + uint8_t found[MAX_SLAVES]; + init_addr_array(found); + + while(1) { + scan_bus(found); + + for(int i = 0; i < MAX_SLAVES; i++){ + if( found[i] == 0x00 ) + break; + + uint8_t data = 1; + // send data to found slave address + write_i2c(found[i], &data, 1); + + data = 0; + write_i2c(found[i], &data, 1); + // request update from slave addr at found[i] + //write_i2c(); + } + } } diff --git a/main/init.c b/main/init.c index f336ad0..08177c7 100644 --- a/main/init.c +++ b/main/init.c @@ -24,8 +24,8 @@ static void init_wifi() { // enable 'station' mode (connect to an access point instead of acting like one) cyw43_arch_enable_sta_mode(); - if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CONF_NET_AUTH, CONF_NET_CONN_TIMEOUT)) - panic("cyw43_arch_wifi_connect failed\n"); + // if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CONF_NET_AUTH, CONF_NET_CONN_TIMEOUT)) + // panic("cyw43_arch_wifi_connect failed\n"); printf("connected to Wi-Fi\n"); -- cgit v1.2.3 From 4499d3cdfa2210a3c8be5e93f45fd7286e0d646d Mon Sep 17 00:00:00 2001 From: ThomasintAnker Date: Fri, 24 May 2024 11:21:41 +0200 Subject: pani --- main/i2c.c | 33 +++++++++++++++++++++------------ main/i2c.h | 2 ++ main/main.c | 4 ++-- 3 files changed, 25 insertions(+), 14 deletions(-) (limited to 'main') diff --git a/main/i2c.c b/main/i2c.c index cbf6938..c1f11ea 100644 --- a/main/i2c.c +++ b/main/i2c.c @@ -1,4 +1,5 @@ #include "i2c.h" +#include "init.h" #include #include @@ -7,8 +8,9 @@ #include void init_i2c() { - stdio_init_all(); - i2c_init(i2c_default, 100 * 1000); // currently at 100kHz + await_init(); + + i2c_init(I2C_PORT, 100 * 1000); // currently at 100kHz // Initialize I2C pins - sda(16), scl(17) gpio_set_function(SDA_PIN, GPIO_FUNC_I2C); @@ -20,25 +22,25 @@ void init_i2c() { int read_i2c(uint8_t addr, uint8_t *output, size_t len) { // false - finished with bus - return i2c_read_blocking (i2c_default, addr, output, len, false); + return i2c_read_blocking (I2C_PORT, addr, output, len, false); } int write_i2c(uint8_t addr, uint8_t *input, size_t len) { // true to keep master control of bus - return i2c_write_blocking (i2c_default, addr, input, len, true); + return i2c_write_blocking (I2C_PORT, addr, input, len, true); } bool reserved_addr(uint8_t addr) { return (addr & 0x78) == 0 || (addr & 0x78) == 0x78; } -void init_addr_array(uint8_t array[]) { - for(int i = 0; i < MAX_SLAVES; i++){ +void init_addr_array(uint8_t array[], int size) { + for(int i = 0; i < size; i++){ array[i] = 0x00; } } -uint8_t* scan_bus(uint8_t* array) { +uint8_t* scan_bus(uint8_t *array) { int ret; int i = 0; uint8_t rxdata; @@ -49,11 +51,12 @@ uint8_t* scan_bus(uint8_t* array) { if( reserved_addr(addr) ){ ret = PICO_ERROR_GENERIC; }else{ - ret = i2c_read_blocking(i2c_default, addr, &rxdata, 1, false); + ret = i2c_read_blocking(I2C_PORT, addr, &rxdata, 1, false); } // if acknowledged -> ret == number of bytes sent if(ret > 0){ + printf("found i2c slave on addr: %d", addr); array[i] = addr; i++; } @@ -65,27 +68,33 @@ uint8_t* scan_bus(uint8_t* array) { void bus_task() { // scan bus for slaves // send updates at regular intervals + await_init(); + printf("Bus task!"); + return; + int i = 0; uint8_t found[MAX_SLAVES]; - init_addr_array(found); + init_addr_array(found, MAX_SLAVES); while(1) { + printf("Bus scan!"); scan_bus(found); for(int i = 0; i < MAX_SLAVES; i++){ if( found[i] == 0x00 ) break; - uint8_t data = 1; + uint8_t data = 0x01; // send data to found slave address + printf("printing data 1"); write_i2c(found[i], &data, 1); - data = 0; + printf("printing data 0"); + data = 0x02; write_i2c(found[i], &data, 1); // request update from slave addr at found[i] //write_i2c(); } } - } diff --git a/main/i2c.h b/main/i2c.h index 405ae1f..5ad5cfb 100644 --- a/main/i2c.h +++ b/main/i2c.h @@ -3,9 +3,11 @@ #include #include +#include #define SDA_PIN 16 #define SCL_PIN 17 +#define I2C_PORT i2c0 #define MAX_SLAVES 10 /** diff --git a/main/main.c b/main/main.c index b38030f..22287b3 100644 --- a/main/main.c +++ b/main/main.c @@ -24,8 +24,8 @@ int main() { init(); xTaskCreate((TaskFunction_t) blink_task, "blink", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); - xTaskCreate((TaskFunction_t) serve_task, "serve", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); - xTaskCreate((TaskFunction_t) bus_task, "bus", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); + //xTaskCreate((TaskFunction_t) serve_task, "serve", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); + //xTaskCreate((TaskFunction_t) bus_task, "bus", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); vTaskStartScheduler(); } -- cgit v1.2.3 From c00f589d6a1636f3b74be0b27becbca684da8cb7 Mon Sep 17 00:00:00 2001 From: ThomasintAnker Date: Fri, 24 May 2024 12:33:53 +0200 Subject: FIXED HARDFAULT --- main/i2c.c | 4 ---- main/main.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'main') diff --git a/main/i2c.c b/main/i2c.c index c1f11ea..31a1454 100644 --- a/main/i2c.c +++ b/main/i2c.c @@ -8,8 +8,6 @@ #include void init_i2c() { - await_init(); - i2c_init(I2C_PORT, 100 * 1000); // currently at 100kHz // Initialize I2C pins - sda(16), scl(17) @@ -70,8 +68,6 @@ void bus_task() { // send updates at regular intervals await_init(); printf("Bus task!"); - - return; int i = 0; uint8_t found[MAX_SLAVES]; diff --git a/main/main.c b/main/main.c index 22287b3..19dd3cd 100644 --- a/main/main.c +++ b/main/main.c @@ -25,7 +25,7 @@ int main() { xTaskCreate((TaskFunction_t) blink_task, "blink", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); //xTaskCreate((TaskFunction_t) serve_task, "serve", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); - //xTaskCreate((TaskFunction_t) bus_task, "bus", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); + xTaskCreate((TaskFunction_t) bus_task, "bus", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); vTaskStartScheduler(); } -- cgit v1.2.3 From 4fc192eb9ba949276c47c1bbd86164d955d3548c Mon Sep 17 00:00:00 2001 From: ThomasintAnker Date: Sat, 25 May 2024 17:21:04 +0200 Subject: Removed redundant prints --- main/i2c.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'main') diff --git a/main/i2c.c b/main/i2c.c index 31a1454..b324124 100644 --- a/main/i2c.c +++ b/main/i2c.c @@ -54,7 +54,7 @@ uint8_t* scan_bus(uint8_t *array) { // if acknowledged -> ret == number of bytes sent if(ret > 0){ - printf("found i2c slave on addr: %d", addr); + printf("found i2c slave on addr: %d\n", addr); array[i] = addr; i++; } @@ -67,14 +67,13 @@ void bus_task() { // scan bus for slaves // send updates at regular intervals await_init(); - printf("Bus task!"); int i = 0; uint8_t found[MAX_SLAVES]; init_addr_array(found, MAX_SLAVES); while(1) { - printf("Bus scan!"); + // printf("Bus scan!"); scan_bus(found); for(int i = 0; i < MAX_SLAVES; i++){ @@ -83,10 +82,8 @@ void bus_task() { uint8_t data = 0x01; // send data to found slave address - printf("printing data 1"); write_i2c(found[i], &data, 1); - printf("printing data 0"); data = 0x02; write_i2c(found[i], &data, 1); // request update from slave addr at found[i] -- cgit v1.2.3 From 25a4f905a3f93645aee79157f30867b287871163 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Tue, 28 May 2024 11:28:22 +0200 Subject: separate the i2c over tcp from puzzle bus libraries --- client/CMakeLists.txt | 4 +- client/cmd.cpp | 4 +- client/examples/puzbus-hello-world.cpp | 67 ------------------------- client/readme.md | 12 ----- client/sock.cpp | 12 ++--- i2ctcp/i2ctcpv1.c | 54 +++++++++++++++++++++ i2ctcp/i2ctcpv1.h | 71 +++++++++++++++++++++++++++ i2ctcp/include.cmake | 16 ++++++ i2ctcp/lib | 1 + main/CMakeLists.txt | 4 +- main/sock.c | 12 ++--- proto/include.cmake | 16 ------ proto/lib | 1 - proto/puzbusv1.c | 55 --------------------- proto/puzbusv1.h | 89 ---------------------------------- shared/busaddr.h | 20 -------- shared/puzbus.h | 39 +++++++++++++++ 17 files changed, 199 insertions(+), 278 deletions(-) delete mode 100644 client/examples/puzbus-hello-world.cpp create mode 100644 i2ctcp/i2ctcpv1.c create mode 100644 i2ctcp/i2ctcpv1.h create mode 100644 i2ctcp/include.cmake create mode 120000 i2ctcp/lib delete mode 100644 proto/include.cmake delete mode 120000 proto/lib delete mode 100644 proto/puzbusv1.c delete mode 100644 proto/puzbusv1.h delete mode 100644 shared/busaddr.h create mode 100644 shared/puzbus.h (limited to 'main') diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 6aa4b4f..73c703d 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_BUILD_TYPE Debug) project(puzzlebox_client C CXX) -include(../proto/include.cmake) +include(../i2ctcp/include.cmake) add_executable(pbc main.cpp @@ -19,7 +19,7 @@ add_executable(pbc ) target_link_libraries(pbc - puzbus + i2ctcp mpack readline # this is such a common library that I did not bother adding it as a submodule ) diff --git a/client/cmd.cpp b/client/cmd.cpp index 736cf12..a26de13 100644 --- a/client/cmd.cpp +++ b/client/cmd.cpp @@ -3,11 +3,11 @@ #include #include "cmd.h" -#include "puzbusv1.h" +#include "i2ctcpv1.h" #include "sock.h" #include "parse.h" -#include "../shared/busaddr.h" +#include "../shared/puzbus.h" char* consume_token(char* input, const char* ifs) { strtok(input, ifs); diff --git a/client/examples/puzbus-hello-world.cpp b/client/examples/puzbus-hello-world.cpp deleted file mode 100644 index dcc965b..0000000 --- a/client/examples/puzbus-hello-world.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include - -#include "puzbusv1.h" - -int send_message() { - const char* data = "Test message data!"; - struct pb_msg output = { - .addr = 0x39, - .data = (char*) data, - .length = strlen(data), - }; - - char* packed; - size_t size; - if (!pb_write(&output, &packed, &size)) { - printf("error writing!\n"); - return EXIT_FAILURE; - } - - fwrite(packed, sizeof(packed[0]), size, stdout); - fflush(stdout); - - return EXIT_SUCCESS; -} - -int read_message() { - freopen(NULL, "rb", stdin); // allow binary on stdin - struct pb_msg input; - - char buf[4]; // extremely small buffer to test chunked message parsing - size_t bytes = 0; - - while ((bytes = fread(buf, sizeof(buf[0]), sizeof(buf), stdin)) > 0) { - int ret = pb_read(&input, buf, bytes); - - // header read error - if (ret < 0) { - printf("error reading!\n"); - return EXIT_FAILURE; - } - - // continue reading if more bytes needed... - if (ret > 0) continue; - - // message read completely! - printf("address: 0x%02x\n", input.addr); - printf("data: \"%.*s\"\n", input.length, input.data); - free(input.data); - return EXIT_SUCCESS; - } - - // if we reach this point, data was read but it did not contain a complete - // message, and is thus considered a failure - return EXIT_FAILURE; -} - -int main() { - if (!isatty(fileno(stdout))) return send_message(); - if (!isatty(fileno(stdin))) return read_message(); - - printf("please pipe some data in or out to use this program\n"); - return EXIT_SUCCESS; -} - diff --git a/client/readme.md b/client/readme.md index 98cd853..1b4cc34 100644 --- a/client/readme.md +++ b/client/readme.md @@ -1,17 +1,5 @@ # puzzle box client -goal (in order of implementation): -``` -(pbc) help - exit exit pbc - test send a test puzbus message - help show this help - send [debug] send raw message - status show global puzzle box state (main controller state) - reset reset entire game state - ls list connected puzzle modules -``` - ## Send data ``` diff --git a/client/sock.cpp b/client/sock.cpp index f967f64..2d5787d 100644 --- a/client/sock.cpp +++ b/client/sock.cpp @@ -10,7 +10,7 @@ #include -#include "puzbusv1.h" +#include "i2ctcpv1.h" #include "sock.h" #include "rl.h" @@ -72,7 +72,7 @@ void PBSocket::send(const char * buf, size_t buf_sz) { } void PBSocket::sock_task() { - struct pb_msg input; + i2ctcp_msg_t input; while(1) { char buf[80]; @@ -86,11 +86,11 @@ void PBSocket::sock_task() { // skip empty frames if (bytes == 0) continue; - int ret = pb_read(&input, buf, bytes); + int ret = i2ctcp_read(&input, buf, bytes); // header read error if (ret < 0) { - rl_printf("pb_read error!\n"); + rl_printf("i2ctcp_read error!\n"); break; } @@ -106,7 +106,7 @@ void PBSocket::sock_task() { } void i2c_send(uint16_t addr, const char * data, size_t data_size) { - struct pb_msg msg = { + i2ctcp_msg_t msg = { .addr = addr, .data = (char *) data, .length = data_size, @@ -114,7 +114,7 @@ void i2c_send(uint16_t addr, const char * data, size_t data_size) { char* packed; size_t size; - if (!pb_write(&msg, &packed, &size)) return; + if (!i2ctcp_write(&msg, &packed, &size)) return; sock->send(packed, size); } diff --git a/i2ctcp/i2ctcpv1.c b/i2ctcp/i2ctcpv1.c new file mode 100644 index 0000000..36a5dbd --- /dev/null +++ b/i2ctcp/i2ctcpv1.c @@ -0,0 +1,54 @@ +#include +#include + +// MIN() macro +#include + +#include "i2ctcpv1.h" + +int i2ctcp_read(i2ctcp_msg_t * target, const char * buf, size_t buf_sz) { + // a new reader is used per buffer block passed to this function + mpack_reader_t reader; + mpack_reader_init_data(&reader, buf, buf_sz); + + // at start of message + if (target->_rdata == 0) { + // NOTE: The entire start of a message needs to be readable from the buffer + // at this point. When target->addr can be read and target->length is past + // the end of the current buffer block, this function will crash and burn. + // This is a highly unlikely scenario, as i2ctcp_read is called for each + // chunk of a TCP frame, and frames (should) include only one puzzle bus + // message. The check here is kind of optional. + if (buf_sz < 4) return -1; + + target->addr = mpack_expect_u16(&reader); + target->length = target->_rdata = mpack_expect_bin(&reader); + target->data = (char *) malloc(target->length); + } + + // continue reading chunks of target->data until the amount of bytes + // specified in target->length + size_t to_read = MIN(mpack_reader_remaining(&reader, NULL), target->_rdata); + char * data = target->data + target->length - target->_rdata; + mpack_read_bytes(&reader, data, to_read); + target->_rdata -= to_read; + + // if rdata = 0, the message was completely read + return target->_rdata; +} + +void i2ctcp_read_reset(i2ctcp_msg_t * target) { + target->_rdata = 0; +} + +bool i2ctcp_write(const i2ctcp_msg_t * target, char ** buf, size_t * buf_sz) { + mpack_writer_t writer; + mpack_writer_init_growable(&writer, buf, buf_sz); + + mpack_write_u16(&writer, target->addr); + mpack_write_bin(&writer, target->data, target->length); + + // finish writing + return mpack_writer_destroy(&writer) == mpack_ok; +} + diff --git a/i2ctcp/i2ctcpv1.h b/i2ctcp/i2ctcpv1.h new file mode 100644 index 0000000..799b668 --- /dev/null +++ b/i2ctcp/i2ctcpv1.h @@ -0,0 +1,71 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \brief I2C over TCP message (v1) */ +struct i2ctcp_msg { + uint16_t addr; //!< I^2^C address + char * data; //!< message content + size_t length; //!< message size + size_t _rdata; //!< \private remaining bytes to read until message is complete +}; +typedef struct i2ctcp_msg i2ctcp_msg_t; + +/** + * \brief Read chunk of input stream, and store resulting message in \p target + * + * This function is called for each chunk of data from an input stream, and + * will parse the next puzzle bus message into \p target. The input stream is + * assumed to only contain messages encoded by \p i2ctcp_write() + * + * \param target pointer to struct that will contain the finished message data + * \param buf pointer to input stream data chunk + * \param buf_sz size of \p buf + * + * \returns Integer representing amount of bytes required to finish message, or + * -1 if the message header could not be read. If this function returns 0, the + * message in \p target is complete. + * + * \note target->data will automatically be allocated by this function, even if + * the message is not fully parsed. This variable must be `free()`d by the + * caller after each complete message to prevent memory leaks. + */ +int i2ctcp_read(i2ctcp_msg_t * target, const char * buf, size_t buf_sz); + +/** + * \brief reset the remaining message data counter + * + * Calling this function has the effect of forcing \c i2ctcp_read() to parse + * the next buffer chunk as the start of a new message. This function may be + * called before reading a TCP frame's data to mitigate any synchronization + * issues arising from earlier corrupt or otherwise malformed messages. + */ +void i2ctcp_read_reset(i2ctcp_msg_t * target); + +/** + * \brief Allocate and write a msgpack-formatted message to \p buf + * + * This function allocates a buffer large enough to fit the message specified + * in \p target, and encodes the data in \p target in a format that can be + * decoded later using \p i2ctcp_read() + * + * \param target pointer to struct that contains the message data + * \param buf pointer to \c char* that will contain the formatted message + * \param buf_sz pointer to \c size_t that will represent the final size of \p buf + * + * \returns boolean true if a the message could be encoded successfully, false + * if there was some kind of error + * + * \note the pointer stored in \p buf must be `free()`d by the caller afterwards + */ +bool i2ctcp_write(const i2ctcp_msg_t * target, char ** buf, size_t * buf_sz); + +#ifdef __cplusplus +} +#endif + diff --git a/i2ctcp/include.cmake b/i2ctcp/include.cmake new file mode 100644 index 0000000..d755b57 --- /dev/null +++ b/i2ctcp/include.cmake @@ -0,0 +1,16 @@ +include_directories(${CMAKE_CURRENT_LIST_DIR}) +add_library(i2ctcp STATIC + ${CMAKE_CURRENT_LIST_DIR}/i2ctcpv1.c + ) + +# mpack +include_directories(${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack) +add_library(mpack STATIC + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-common.c + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-expect.c + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-node.c + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-platform.c + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-reader.c + ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-writer.c + ) + diff --git a/i2ctcp/lib b/i2ctcp/lib new file mode 120000 index 0000000..dc598c5 --- /dev/null +++ b/i2ctcp/lib @@ -0,0 +1 @@ +../lib \ No newline at end of file diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 30685a4..6390d7c 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -7,7 +7,7 @@ set(PICO_BOARD pico_w) include(lib/pico-sdk/pico_sdk_init.cmake) include(lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake) -include(../proto/include.cmake) +include(../i2ctcp/include.cmake) project(puzzlebox_main C CXX ASM) @@ -33,7 +33,7 @@ target_link_libraries(main hardware_i2c FreeRTOS-Kernel FreeRTOS-Kernel-Heap4 - puzbus + i2ctcp mpack ) diff --git a/main/sock.c b/main/sock.c index 4f50981..fe932bb 100644 --- a/main/sock.c +++ b/main/sock.c @@ -7,16 +7,16 @@ #include "init.h" #include "config.h" -#include "puzbusv1.h" +#include "i2ctcpv1.h" #include "sock.h" struct netconn* current_connection = NULL; -struct pb_msg recv_msg; +i2ctcp_msg_t recv_msg; void i2c_send(uint16_t addr, const char * data, size_t data_size) { if (current_connection == NULL) return; - struct pb_msg send_msg = { + i2ctcp_msg_t send_msg = { .addr = addr, .data = (char *) data, .length = data_size, @@ -25,7 +25,7 @@ void i2c_send(uint16_t addr, const char * data, size_t data_size) { char * buf; size_t buf_sz; - if (!pb_write(&send_msg, &buf, &buf_sz)) return; + if (!i2ctcp_write(&send_msg, &buf, &buf_sz)) return; // NOTE: netconn does return an error code, but the data needs to be freed // whether netconn throws an error or not, so it remains unused @@ -47,7 +47,7 @@ void i2c_recv(uint16_t addr, const char * data, size_t data_size) { } void recv_handler(struct netconn* conn, struct netbuf* buf) { - pb_read_reset(&recv_msg); + i2ctcp_read_reset(&recv_msg); do { char* data; @@ -55,7 +55,7 @@ void recv_handler(struct netconn* conn, struct netbuf* buf) { netbuf_data(buf, (void**)&data, &len); // continue early if more data is needed to complete message - if (!pb_read(&recv_msg, data, len)) continue; + if (!i2ctcp_read(&recv_msg, data, len)) continue; // forward received message to puzzle bus i2c_recv(recv_msg.addr, recv_msg.data, recv_msg.length); diff --git a/proto/include.cmake b/proto/include.cmake deleted file mode 100644 index ac1305e..0000000 --- a/proto/include.cmake +++ /dev/null @@ -1,16 +0,0 @@ -include_directories(${CMAKE_CURRENT_LIST_DIR}) -add_library(puzbus STATIC - ${CMAKE_CURRENT_LIST_DIR}/puzbusv1.c - ) - -# mpack -include_directories(${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack) -add_library(mpack STATIC - ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-common.c - ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-expect.c - ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-node.c - ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-platform.c - ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-reader.c - ${CMAKE_CURRENT_LIST_DIR}/lib/mpack/src/mpack/mpack-writer.c - ) - diff --git a/proto/lib b/proto/lib deleted file mode 120000 index dc598c5..0000000 --- a/proto/lib +++ /dev/null @@ -1 +0,0 @@ -../lib \ No newline at end of file diff --git a/proto/puzbusv1.c b/proto/puzbusv1.c deleted file mode 100644 index 73deda5..0000000 --- a/proto/puzbusv1.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include - -// MIN() macro -#include -// TODO: check if this works on pico as well - -#include "puzbusv1.h" - -int pb_read(struct pb_msg * target, const char * buf, size_t buf_sz) { - // a new reader is used per buffer block passed to this function - mpack_reader_t reader; - mpack_reader_init_data(&reader, buf, buf_sz); - - // at start of message - if (target->_rdata == 0) { - // NOTE: The entire start of a message needs to be readable from the buffer - // at this point. When target->addr can be read and target->length is past - // the end of the current buffer block, this function will crash and burn. - // This is a highly unlikely scenario, as pb_read is called for each chunk - // of a TCP frame, and frames (should) include only one puzzle bus message. - // The check here is kind of optional. - if (buf_sz < 4) return -1; - - target->addr = mpack_expect_u16(&reader); - target->length = target->_rdata = mpack_expect_bin(&reader); - target->data = (char *) malloc(target->length); - } - - // continue reading chunks of target->data until the amount of bytes - // specified in target->length - size_t to_read = MIN(mpack_reader_remaining(&reader, NULL), target->_rdata); - char * data = target->data + target->length - target->_rdata; - mpack_read_bytes(&reader, data, to_read); - target->_rdata -= to_read; - - // if rdata = 0, the message was completely read - return target->_rdata; -} - -void pb_read_reset(struct pb_msg * target) { - target->_rdata = 0; -} - -bool pb_write(const struct pb_msg * target, char ** buf, size_t * buf_sz) { - mpack_writer_t writer; - mpack_writer_init_growable(&writer, buf, buf_sz); - - mpack_write_u16(&writer, target->addr); - mpack_write_bin(&writer, target->data, target->length); - - // finish writing - return mpack_writer_destroy(&writer) == mpack_ok; -} - diff --git a/proto/puzbusv1.h b/proto/puzbusv1.h deleted file mode 100644 index 9f4f8e5..0000000 --- a/proto/puzbusv1.h +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \brief Puzzle bus message (v1) */ -struct pb_msg { - uint16_t addr; //!< I^2^C address - char * data; //!< message content - size_t length; //!< message size - size_t _rdata; //!< \private remaining bytes to read until message is complete -}; - -/** - * \brief Read chunk of input stream, and store resulting message in \p target - * - * This function is called for each chunk of data from an input stream, and - * will parse the next puzzle bus message into \p target. The input stream is - * assumed to only contain messages encoded by \p pb_write() - * - * \param target pointer to struct that will contain the finished message data - * \param buf pointer to input stream data chunk - * \param buf_sz size of \p buf - * - * \returns Integer representing amount of bytes required to finish message, or - * -1 if the message header could not be read. If this function returns 0, the - * message in \p target is complete. - * - * \note target->data will automatically be allocated by this function, even if - * the message is not fully parsed. This variable must be `free()`d by the - * caller after each complete message to prevent memory leaks. - */ -int pb_read(struct pb_msg * target, const char * buf, size_t buf_sz); - -/** - * \brief reset the remaining message data counter - * - * Calling this function has the effect of forcing \c pb_read() to parse the - * next buffer chunk as the start of a new message. This function may be called - * before reading a TCP frame's data to mitigate any synchronization issues - * arising from earlier corrupt or otherwise malformed messages. - */ -void pb_read_reset(struct pb_msg * target); - -/** - * \brief Allocate and write a msgpack-formatted message to \p buf - * - * This function allocates a buffer large enough to fit the message specified - * in \p target, and encodes the data in \p target in a format that can be - * decoded later using \p pb_read() - * - * \param target pointer to struct that contains the message data - * \param buf pointer to \c char* that will contain the formatted message - * \param buf_sz pointer to \c size_t that will represent the final size of \p buf - * - * \returns boolean true if a the message could be encoded successfully, false - * if there was some kind of error - * - * \note the pointer stored in \p buf must be `free()`d by the caller afterwards - */ -bool pb_write(const struct pb_msg * target, char ** buf, size_t * buf_sz); - -/** - * \brief I^2^C puzzle bus command types - * - * The first byte of a puzzle bus message's data indicates the command type. - */ -enum pb_cmd { - PB_CMD_READ, //!< read a puzzle module property - PB_CMD_WRITE, //!< write to a puzzle module property - // PB_CMD_UPDATE, //!< request an update -}; - -/** \brief Puzzle bus global states */ -enum pb_global_state { - PB_GS_NOINIT, //!< uninitialized (only used by puzzle modules) - PB_GS_IDLE, //!< puzzle not started yet - PB_GS_PLAYING, //!< puzzle actively being solved - PB_GS_SOLVED, //!< puzzle completed -}; - -#ifdef __cplusplus -} -#endif - diff --git a/shared/busaddr.h b/shared/busaddr.h deleted file mode 100644 index 5879afe..0000000 --- a/shared/busaddr.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -/** \file bus address reference */ - -// Adafruit NeoTrellis modules -#define BUSADDR_ADA_NEO_1 0x2E -#define BUSADDR_ADA_NEO_2 0x2F -#define BUSADDR_ADA_NEO_3 0x30 -#define BUSADDR_ADA_NEO_4 0x32 - -// TODO: ??? -#define BUSADDR_MOD_NEOTRELLIS 0 -#define BUSADDR_MOD_SOFTWARE 0 -#define BUSADDR_MOD_HARDWARE 0 -#define BUSADDR_MOD_VAULT 0 -#define BUSADDR_MOD_AUTOMATION 0 - -// main controller -#define BUSADDR_MAIN 0x00 - diff --git a/shared/puzbus.h b/shared/puzbus.h new file mode 100644 index 0000000..59a8867 --- /dev/null +++ b/shared/puzbus.h @@ -0,0 +1,39 @@ +#pragma once + +/** \file bus address reference */ + +// Adafruit NeoTrellis modules +#define BUSADDR_ADA_NEO_1 0x2E +#define BUSADDR_ADA_NEO_2 0x2F +#define BUSADDR_ADA_NEO_3 0x30 +#define BUSADDR_ADA_NEO_4 0x32 + +// TODO: ??? +#define BUSADDR_MOD_NEOTRELLIS 0 +#define BUSADDR_MOD_SOFTWARE 0 +#define BUSADDR_MOD_HARDWARE 0 +#define BUSADDR_MOD_VAULT 0 +#define BUSADDR_MOD_AUTOMATION 0 + +// main controller +#define BUSADDR_MAIN 0x00 + +/** + * \brief puzzle bus command types + * + * The first byte of a puzzle bus message's data indicates the command type. + */ +enum pb_cmd { + PB_CMD_READ, //!< read a puzzle module property + PB_CMD_WRITE, //!< write to a puzzle module property + // PB_CMD_UPDATE, //!< request an update +}; + +/** \brief Puzzle bus global states */ +enum pb_global_state { + PB_GS_NOINIT, //!< uninitialized (only used by puzzle modules) + PB_GS_IDLE, //!< puzzle not started yet + PB_GS_PLAYING, //!< puzzle actively being solved + PB_GS_SOLVED, //!< puzzle completed +}; + -- cgit v1.2.3