diff options
author | ThomasintAnker <thomasintanker1@gmail.com> | 2024-06-18 16:23:51 +0200 |
---|---|---|
committer | ThomasintAnker <thomasintanker1@gmail.com> | 2024-06-18 16:23:51 +0200 |
commit | a55d0bed6240c54f6173b1e38e80212c02c302de (patch) | |
tree | 07c15eebc8cd84e1071a3f72d3c74475017372f3 /main | |
parent | b45b5d04daa29fcdd456233a931dcbb5b287769f (diff) | |
parent | 245fde65808ce902064ab438296f04f691d007e7 (diff) |
Merge branch 'master' into wip/handover
Diffstat (limited to 'main')
-rw-r--r-- | main/CMakeLists.txt | 11 | ||||
-rw-r--r-- | main/blink.c | 16 | ||||
-rw-r--r-- | main/blink.h | 4 | ||||
l--------- | main/compile_commands.json | 1 | ||||
-rw-r--r-- | main/config.def.h | 75 | ||||
-rw-r--r-- | main/i2c.c | 179 | ||||
-rw-r--r-- | main/i2c.h | 47 | ||||
-rw-r--r-- | main/init.c | 36 | ||||
-rw-r--r-- | main/init.h | 29 | ||||
-rw-r--r-- | main/main.c | 22 | ||||
-rw-r--r-- | main/mod.c | 5 | ||||
-rw-r--r-- | main/readme.md | 24 | ||||
-rw-r--r-- | main/sock.c | 6 | ||||
-rw-r--r-- | main/sock.h | 2 | ||||
-rw-r--r-- | main/tasks.c | 17 | ||||
-rw-r--r-- | main/tasks.h | 4 |
16 files changed, 212 insertions, 266 deletions
diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index cf23839..7a0b136 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -7,8 +7,9 @@ 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(../i2ctcp/include.cmake) -include(../shared/include.cmake) +add_subdirectory(lib/mpack) +add_subdirectory(lib/i2ctcp) +add_subdirectory(lib/pbdrv) project(puzzlebox_main C CXX ASM) @@ -19,6 +20,9 @@ add_executable(main init.c sock.c i2c.c + mod.c + tasks.c + blink.c ) pico_enable_stdio_usb(main 1) @@ -27,7 +31,7 @@ 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_include_directories(main PRIVATE .) target_link_libraries(main pico_cyw43_arch_lwip_sys_freertos pico_stdlib @@ -36,5 +40,6 @@ target_link_libraries(main FreeRTOS-Kernel-Heap4 i2ctcp mpack + pbdrv-mod ) diff --git a/main/blink.c b/main/blink.c new file mode 100644 index 0000000..956e910 --- /dev/null +++ b/main/blink.c @@ -0,0 +1,16 @@ +#include <FreeRTOS.h> +#include <task.h> +#include <pico/cyw43_arch.h> + +#include "blink.h" +#include "config.h" + +void blink_task() { + while (true) { + cyw43_arch_gpio_put(CFG_LED_PIN, 1); + vTaskDelay(50 / portTICK_PERIOD_MS); + cyw43_arch_gpio_put(CFG_LED_PIN, 0); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } +} + diff --git a/main/blink.h b/main/blink.h new file mode 100644 index 0000000..51c5f32 --- /dev/null +++ b/main/blink.h @@ -0,0 +1,4 @@ +#pragma once + +void blink_task(); + diff --git a/main/compile_commands.json b/main/compile_commands.json deleted file mode 120000 index 25eb4b2..0000000 --- a/main/compile_commands.json +++ /dev/null @@ -1 +0,0 @@ -build/compile_commands.json
\ No newline at end of file diff --git a/main/config.def.h b/main/config.def.h index 7fcaed9..3d325fe 100644 --- a/main/config.def.h +++ b/main/config.def.h @@ -1,17 +1,72 @@ #pragma once #include <pico/cyw43_arch.h> +#include <cyw43_country.h> -// 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 10e3 +/** + * \name Network (Wi-Fi) configuration + * \{ + */ +#ifndef CFG_NET_SSID +//! network name (SSID) +#define CFG_NET_SSID "" +#ifndef CFG_NET_DISABLE +//! disable network communication +#define CFG_NET_DISABLE +#warning No SSID defined! Disabling network communication! +#endif +#endif -#include <cyw43_country.h> -#define CONF_NET_COUNTRY CYW43_COUNTRY_NETHERLANDS +#ifndef CFG_NET_PASS +//! network password +#define CFG_NET_PASS "" +#endif + +#ifndef CFG_NET_AUTH +//! network security type +#define CFG_NET_AUTH CYW43_AUTH_OPEN +#endif + +#ifndef CFG_NET_CONN_TIMEOUT +//! max duration (milliseconds) for establishing wifi connection +#define CFG_NET_CONN_TIMEOUT 10e3 +#endif + +#ifdef CFG_NET_DISABLE +#undef CFG_NET_COUNTRY +#define CFG_NET_COUNTRY CYW43_COUNTRY_WORLDWIDE +#endif +#ifndef CFG_NET_COUNTRY +//! radio communications country +#define CFG_NET_COUNTRY CYW43_COUNTRY_NETHERLANDS +#endif +/** \} */ + +/** + * \name i2ctcp server configuration + * \{ + */ +#ifndef CFG_SRV_PORT +//! i2ctcp server port +#define CFG_SRV_PORT 9191 +#endif + +#ifdef CFG_NET_DISABLE +//! disable the i2ctcp server +#define CFG_SRV_DISABLE +#endif +/** \} */ -#define CONF_SRV_PORT 9191 +#ifndef CFG_LED_PIN +//! status LED pin +#define CFG_LED_PIN CYW43_WL_GPIO_LED_PIN +#endif -#define LED_PIN CYW43_WL_GPIO_LED_PIN +#ifndef CFG_SDA_PIN +//! I^2^C SDA pin +#define CFG_SDA_PIN 16 +#endif +#ifndef CFG_SCL_PIN +//! I^2^C SCL pin +#define CFG_SCL_PIN 17 +#endif @@ -1,8 +1,5 @@ -#include "i2c.h" -#include "init.h" -#include "sock.h" -#include "pb/types.h" - +#include <FreeRTOS.h> +#include <task.h> #include <stdio.h> #include <stddef.h> #include <stdint.h> @@ -10,129 +7,65 @@ #include <pico/stdlib.h> #include <hardware/i2c.h> -#include <lwip/opt.h> -#include <lwip/sys.h> -#include <lwip/api.h> -#include <string.h> - -uint8_t found[MAX_SLAVES]; -extern struct netconn* current_connection; - -void init_i2c() { - i2c_init(I2C_PORT, 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_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_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_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[], int size) { - for(int i = 0; i < size; i++){ - array[i] = 0x00; - } -} - -int write_read_i2c(uint8_t addr, uint8_t *input, size_t input_len, uint8_t *output, size_t output_len){ - // herhaalde start conditie voor direct lezen na i2c write (?) - int ret = write_i2c(addr, input, input_len); - if (ret < 0) { - printf("Write failure while writing data to bus.\n"); - return ret; - } - - // wait for response - absolute_time_t start_time = get_absolute_time(); - while ( absolute_time_diff_us(start_time, get_absolute_time()) / 1000 < MAX_TIMEOUT_TIME ){ - ret = read_i2c(addr, output, output_len); - if( ret > 0 ) { - return ret; - } - sleep_ms(1); - } - - printf("Timeout occurred while waiting for slave response.\n"); - return -1; -} - -// Make sure that current addresses are checked (modules), and invalid addresses are ignore (neotrellis slave) -uint8_t* scan_bus(uint8_t *array) { - int ret; - int i = 0; - uint8_t * rxdata; - uint8_t * handshake_data; - init_addr_array(array, MAX_SLAVES); - - for(int addr = 1; addr < (1<<7); addr++) { - // fix handshake - ret = read_i2c(addr, rxdata, 1); - - if ( ret <= 0 ) - continue; - - char buf[80]; - size_t s = snprintf(buf, 80,"found i2c puzzle module at address: 0x%02x\n", addr); - netconn_write(current_connection, buf, s, NETCONN_COPY); - printf("%.*s", s, buf); - - // do handshake - ret = write_read_i2c(addr, (uint8_t*)pb_magic_msg, sizeof(pb_magic_msg), handshake_data, sizeof(pb_magic_res)); // fix data + length + everything - - if ( ret != sizeof(pb_magic_res)) - continue; - - if ( ret > 0 && (memcmp(handshake_data, pb_magic_res, sizeof(pb_magic_res)) == 0)) { - printf("this was an actual device!!!1111!\n"); - char buf[80]; - size_t s = snprintf(buf, 80,"found i2c puzzle module at address: 0x%02x\n"); - netconn_write(current_connection, buf, s, NETCONN_COPY); - - array[i] = addr; - i++; - } - } - - return array; +#include "i2c.h" +#include "pb-mod.h" + +// 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 +// // 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\n", addr); +// array[i] = addr; +// i++; +// } +// } +// +// return array; +// } + +void pbdrv_i2c_recv(const uint8_t * a, size_t b) { + printf("%.*s", b, a); } void bus_task() { // scan bus for slaves // send updates at regular intervals - await_init(); + vTaskDelay(1000 / portTICK_PERIOD_MS); - scan_bus(found); - - while(1) { - // add check if bus is in use - - uint8_t data; - for(int i = 0; i < MAX_SLAVES; i++){ - if( found[i] == 0x00 ) - continue; - - read_i2c(found[i], &data, 2); - if(data > 0) { - printf("Data: %d", data); - } - - } - - sleep_ms(1000); // wait for one second before next loop + // int i = 0; + // uint8_t found[MAX_SLAVES]; + // init_addr_array(found, MAX_SLAVES); + + while (true) { + vTaskDelay(10 / portTICK_PERIOD_MS); + pbdrv_i2c_send(0x69, (uint8_t *) "bbbbbbbb", 9); } + + // while(1) { + // // printf("Bus scan!"); + // scan_bus(found); + + // for(int i = 0; i < MAX_SLAVES; i++){ + // if( found[i] == 0x00 ) + // break; + // + // uint8_t data = 0x01; + // // send data to found slave address + // write_i2c(found[i], &data, 1); + + // data = 0x02; + // write_i2c(found[i], &data, 1); + // // request update from slave addr at found[i] + // //write_i2c(); + // } + // } } + @@ -2,52 +2,9 @@ // https://github.com/raspberrypi/pico-examples/tree/master/i2c // https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html -#include <stddef.h> -#include <stdint.h> -#include <hardware/i2c.h> - -#define SDA_PIN 16 -#define SCL_PIN 17 -#define I2C_PORT i2c0 #define MAX_SLAVES 10 #define MAX_TIMEOUT_TIME 50 //ms -/** - * \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. - * \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 -*/ -int write_read_i2c(uint8_t addr, uint8_t *input, size_t input_len, uint8_t *output, size_t output_len); - -uint8_t* scan_bus(uint8_t *array); - -/** \brief looking for slave addresses and requesting updates */ +//! looking for slave addresses and requesting updates void bus_task(); + diff --git a/main/init.c b/main/init.c index 4ab373e..bd00c04 100644 --- a/main/init.c +++ b/main/init.c @@ -1,22 +1,20 @@ -#include "config.h" -#include "init.h" -#include "i2c.h" - #include <FreeRTOS.h> #include <task.h> -#include <event_groups.h> #include <pico/stdio.h> #include <pico/cyw43_arch.h> -EventGroupHandle_t init_complete; +#include "config.h" +#include "init.h" +#include "tasks.h" +#include "drv/rp2040/mod.h" static void init_stdio() { stdio_init_all(); } static void init_cyw34() { - if (cyw43_arch_init_with_country(CONF_NET_COUNTRY)) + if (cyw43_arch_init_with_country(CFG_NET_COUNTRY)) panic("cyw43_arch_init_with_country failed\n"); } @@ -24,30 +22,32 @@ static void init_wifi() { // enable 'station' mode (connect to an access point instead of acting like one) cyw43_arch_enable_sta_mode(); - /* WERKT GEWOON NIET MET DEZE LIJNEN CODE */ - if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CONF_NET_AUTH, CONF_NET_CONN_TIMEOUT)) + if (cyw43_arch_wifi_connect_timeout_ms(CFG_NET_SSID, CFG_NET_PASS, CFG_NET_AUTH, CFG_NET_CONN_TIMEOUT)) panic("cyw43_arch_wifi_connect failed\n"); - /* WERKT GEWOON NIET MET DEZE LIJNEN CODE */ - - printf("connected to Wi-Fi\n"); // TODO: announce hostname(?) } +static void init_i2c() { + gpio_set_function(CFG_SDA_PIN, GPIO_FUNC_I2C); + gpio_set_function(CFG_SCL_PIN, GPIO_FUNC_I2C); + + pbdrv_setup(); +} + static void async_init() { init_cyw34(); init_i2c(); +#ifndef CFG_NET_DISABLE init_wifi(); - - xEventGroupSetBits(init_complete, 1); +#endif + init_tasks(); // delete self vTaskDelete(NULL); } void init() { - init_complete = xEventGroupCreate(); - // used for debug `printf` and `panic` on errors init_stdio(); @@ -55,7 +55,3 @@ void init() { 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.h b/main/init.h index de9023c..73d2773 100644 --- a/main/init.h +++ b/main/init.h @@ -1,38 +1,11 @@ #pragma once -#include <FreeRTOS.h> -#include <event_groups.h> - -/** - * \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 + * \brief initialize the main controller * * 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.c b/main/main.c index 7558a0b..7c1bb6a 100644 --- a/main/main.c +++ b/main/main.c @@ -1,32 +1,10 @@ #include <FreeRTOS.h> #include <task.h> -#include <pico/stdlib.h> -#include <pico/time.h> - -#include "config.h" #include "init.h" -#include "sock.h" -#include "i2c.h" - -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); - } -} 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); - vTaskStartScheduler(); while(1) { diff --git a/main/mod.c b/main/mod.c new file mode 100644 index 0000000..b34bbc9 --- /dev/null +++ b/main/mod.c @@ -0,0 +1,5 @@ +#include "pb-mod.h" + +const char * PBDRV_MOD_NAME = "main controller"; +const i2c_addr_t PBDRV_MOD_ADDR = 0x20; + diff --git a/main/readme.md b/main/readme.md index 425a00b..28fcfad 100644 --- a/main/readme.md +++ b/main/readme.md @@ -5,17 +5,23 @@ 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) +2. create a `config.h` file and define some options (see `config.def.h` for all + options): + ```c + #pragma once -alternatively, a makefile is provided for convenience + #define CFG_NET_SSID "network name" + #define CFG_NET_PASS "network password" + #define CFG_NET_AUTH CYW43_AUTH_WPA2_AES_PSK -## "flashing" + #include "config.def.h" + ``` +3. use CMake to build -1. [build](#building) -2. (re)connect the raspberry pi pico while holding the BOOTSEL button (this is - the only button) +## flashing + +1. build +2. hold the BOOTSEL button while resetting the pico (by power cycling or + pulling pin 30 (RUN) to GND) 3. `picotool load build/main.uf2` diff --git a/main/sock.c b/main/sock.c index af25d97..5d75e8f 100644 --- a/main/sock.c +++ b/main/sock.c @@ -81,14 +81,12 @@ void accept_handler(struct netconn* conn) { } void serve_task() { - await_init(); - printf("starting server...\n"); struct netconn* conn = netconn_new(NETCONN_TCP); - netconn_bind(conn, IP_ADDR_ANY, CONF_SRV_PORT); + netconn_bind(conn, IP_ADDR_ANY, CFG_SRV_PORT); netconn_listen(conn); - printf("listening on %s:%d\n", ip4addr_ntoa(netif_ip4_addr(netif_list)), CONF_SRV_PORT); + printf("listening on %s:%d\n", ip4addr_ntoa(netif_ip4_addr(netif_list)), CFG_SRV_PORT); while (1) { struct netconn* incoming; if (netconn_accept(conn, &incoming) == ERR_OK) diff --git a/main/sock.h b/main/sock.h index f2db35d..61828fb 100644 --- a/main/sock.h +++ b/main/sock.h @@ -3,7 +3,7 @@ #include <stdint.h> #include <stddef.h> -/** \brief start listening for TCP socket requests */ +//! start listening for TCP socket requests void serve_task(); void i2c_send(uint16_t addr, const char * data, size_t data_size); diff --git a/main/tasks.c b/main/tasks.c new file mode 100644 index 0000000..253c47b --- /dev/null +++ b/main/tasks.c @@ -0,0 +1,17 @@ +#include <FreeRTOS.h> +#include <task.h> + +#include "config.h" +#include "tasks.h" + +#include "blink.h" +#include "i2c.h" +#include "sock.h" + +void init_tasks() { + xTaskCreate((TaskFunction_t) blink_task, "blink", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); +#ifndef CFG_SRV_DISABLE + xTaskCreate((TaskFunction_t) serve_task, "serve", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); +#endif + xTaskCreate((TaskFunction_t) bus_task, "bus", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); +} diff --git a/main/tasks.h b/main/tasks.h new file mode 100644 index 0000000..002f830 --- /dev/null +++ b/main/tasks.h @@ -0,0 +1,4 @@ +#pragma once + +void init_tasks(); + |