aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-06-08 19:20:49 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-06-08 19:20:49 +0200
commitfeaa43f37c01cf832fed17572d915e5709231893 (patch)
tree37f63dee764e75ad2dd1485f06c583b5473ff6fc
parente4b241c8ec4f12fe6ac479c2153cc540830e6a5d (diff)
WIP raspberry pi pico pbdrv
-rw-r--r--lib/pbdrv/CMakeLists.txt37
-rw-r--r--lib/pbdrv/drv/arduino/cfg.cmake7
-rw-r--r--lib/pbdrv/drv/arduino/mod.h2
-rw-r--r--lib/pbdrv/drv/rp2040/cfg.cmake7
-rw-r--r--lib/pbdrv/drv/rp2040/mod.c50
-rw-r--r--lib/pbdrv/drv/rp2040/mod.h13
-rw-r--r--main/CMakeLists.txt3
-rw-r--r--main/config.def.h26
-rw-r--r--main/i2c.c90
-rw-r--r--main/i2c.h34
-rw-r--r--main/init.c10
-rw-r--r--main/main.c6
-rw-r--r--main/mod.c5
13 files changed, 157 insertions, 133 deletions
diff --git a/lib/pbdrv/CMakeLists.txt b/lib/pbdrv/CMakeLists.txt
index dfaac01..e70cb5b 100644
--- a/lib/pbdrv/CMakeLists.txt
+++ b/lib/pbdrv/CMakeLists.txt
@@ -12,34 +12,17 @@ project(pbdrv C CXX)
add_subdirectory(../mpack ${CMAKE_CURRENT_BINARY_DIR}/mpack)
-if(DEFINED ARDUINO)
- set(PBDRV_ARDUINO true)
-endif()
-
-include_directories(.)
-add_library(pbdrv STATIC
- pb-read.c
- pb-write.c
- )
-target_link_libraries(pbdrv
- mpack
- )
+# generic puzzle bus (de)serializer library
+add_library(pbdrv STATIC pb-read.c pb-write.c)
+target_link_libraries(pbdrv mpack)
target_include_directories(pbdrv SYSTEM INTERFACE .)
-list(APPEND PBDRV_SRCS pb-mod.c)
-
-if(PBDRV_ARDUINO)
- list(APPEND PBDRV_SRCS drv/arduino/mod.cpp)
-endif()
-
-add_library(pbdrv-mod STATIC ${PBDRV_SRCS})
+# puzzle bus module specific code (superset of pbdrv)
+add_library(pbdrv-mod STATIC pb-mod.c)
target_link_libraries(pbdrv-mod pbdrv)
-# add_dependencies(pbdrv-mod pbdrv)
-
-if(PBDRV_ARDUINO)
- target_link_arduino_libraries(pbdrv-mod
- core
- Wire
- )
-endif()
+target_include_directories(pbdrv-mod SYSTEM INTERFACE .)
+
+# supported puzzle bus drivers
+include(drv/arduino/cfg.cmake)
+include(drv/rp2040/cfg.cmake)
diff --git a/lib/pbdrv/drv/arduino/cfg.cmake b/lib/pbdrv/drv/arduino/cfg.cmake
new file mode 100644
index 0000000..36716e3
--- /dev/null
+++ b/lib/pbdrv/drv/arduino/cfg.cmake
@@ -0,0 +1,7 @@
+if(NOT DEFINED ARDUINO)
+ return()
+endif()
+
+target_sources(pbdrv-mod PRIVATE "${CMAKE_CURRENT_LIST_DIR}/mod.cpp")
+target_link_arduino_libraries(pbdrv-mod core Wire)
+
diff --git a/lib/pbdrv/drv/arduino/mod.h b/lib/pbdrv/drv/arduino/mod.h
index e545d9b..079941a 100644
--- a/lib/pbdrv/drv/arduino/mod.h
+++ b/lib/pbdrv/drv/arduino/mod.h
@@ -1,7 +1,5 @@
#pragma once
-#include "../../pb-mod.h"
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/lib/pbdrv/drv/rp2040/cfg.cmake b/lib/pbdrv/drv/rp2040/cfg.cmake
new file mode 100644
index 0000000..0fbad18
--- /dev/null
+++ b/lib/pbdrv/drv/rp2040/cfg.cmake
@@ -0,0 +1,7 @@
+if(NOT PICO_PLATFORM STREQUAL "rp2040")
+ return()
+endif()
+
+target_sources(pbdrv-mod PRIVATE "${CMAKE_CURRENT_LIST_DIR}/mod.c")
+target_link_libraries(pbdrv-mod hardware_i2c pico_i2c_slave)
+
diff --git a/lib/pbdrv/drv/rp2040/mod.c b/lib/pbdrv/drv/rp2040/mod.c
new file mode 100644
index 0000000..26882f7
--- /dev/null
+++ b/lib/pbdrv/drv/rp2040/mod.c
@@ -0,0 +1,50 @@
+#include "mod.h"
+
+#include "../../pb.h"
+#include "../../pb-types.h"
+#include "../../pb-mod.h"
+
+#include <hardware/i2c.h>
+#include <hardware/gpio.h>
+#include <pico/i2c_slave.h>
+
+#define PBDRV_I2C i2c0
+#define BUF_SIZE 256
+
+// NOTE: this function is called from the I2C ISR, and should return as quickly
+// as possible.
+static void recv_event(i2c_inst_t *i2c, i2c_slave_event_t event) {
+ uint8_t data[BUF_SIZE];
+ size_t size = 0;
+ // pbdrv_i2c_recv(NULL, 0);
+
+ switch (event) {
+ case I2C_SLAVE_RECEIVE: {
+ if (size == BUF_SIZE) return;
+ data[size++] = i2c_read_byte_raw(PBDRV_I2C);
+ break;
+ }
+ case I2C_SLAVE_FINISH: {
+ // TODO: handle this w/ queue mechanism instead?
+ pbdrv_i2c_recv(data, size);
+ size = 0;
+ break;
+ }
+ default: break;
+ }
+}
+
+void pbdrv_setup() {
+ i2c_init(PBDRV_I2C, PB_CLOCK_SPEED_HZ);
+ i2c_slave_init(PBDRV_I2C, PBDRV_MOD_ADDR, &recv_event);
+}
+
+__weak void pbdrv_i2c_send(i2c_addr_t addr, const uint8_t * buf, size_t sz) {
+ i2c_set_slave_mode(PBDRV_I2C, false, PBDRV_MOD_ADDR);
+
+ // false to write stop condition to i2c bus
+ i2c_write_timeout_us(PBDRV_I2C, addr, buf, sz, false, PB_TIMEOUT_US);
+
+ i2c_set_slave_mode(PBDRV_I2C, true, PBDRV_MOD_ADDR);
+}
+
diff --git a/lib/pbdrv/drv/rp2040/mod.h b/lib/pbdrv/drv/rp2040/mod.h
new file mode 100644
index 0000000..0cf2e63
--- /dev/null
+++ b/lib/pbdrv/drv/rp2040/mod.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//! puzzle bus driver setup
+void pbdrv_setup();
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt
index 4c17fba..04e612d 100644
--- a/main/CMakeLists.txt
+++ b/main/CMakeLists.txt
@@ -20,6 +20,7 @@ add_executable(main
init.c
sock.c
i2c.c
+ mod.c
)
pico_enable_stdio_usb(main 1)
@@ -28,7 +29,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
diff --git a/main/config.def.h b/main/config.def.h
index 11612eb..3d325fe 100644
--- a/main/config.def.h
+++ b/main/config.def.h
@@ -6,15 +6,15 @@
* \name Network (Wi-Fi) configuration
* \{
*/
-#ifndef CFG_NET_DISABLE
-
#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
#ifndef CFG_NET_PASS
//! network password
@@ -31,17 +31,14 @@
#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
-
-#else // ifndef CFG_NET_DISABLE
-
-#undef CFG_NET_COUNTRY
-#define CFG_NET_COUNTRY CYW43_COUNTRY_WORLDWIDE
-
-#endif // ifndef CFG_NET_DISABLE
/** \} */
/**
@@ -53,7 +50,7 @@
#define CFG_SRV_PORT 9191
#endif
-#ifndef CFG_NET_DISABLE
+#ifdef CFG_NET_DISABLE
//! disable the i2ctcp server
#define CFG_SRV_DISABLE
#endif
@@ -64,3 +61,12 @@
#define CFG_LED_PIN CYW43_WL_GPIO_LED_PIN
#endif
+#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
+
diff --git a/main/i2c.c b/main/i2c.c
index b324124..43d17bf 100644
--- a/main/i2c.c
+++ b/main/i2c.c
@@ -1,43 +1,14 @@
#include "i2c.h"
#include "init.h"
+#include "pb-mod.h"
+
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <pico/stdlib.h>
#include <hardware/i2c.h>
-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;
- }
-}
-
uint8_t* scan_bus(uint8_t *array) {
int ret;
int i = 0;
@@ -46,11 +17,7 @@ uint8_t* scan_bus(uint8_t *array) {
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_PORT, addr, &rxdata, 1, false);
- }
+ // ret = i2c_read_blocking(I2C_PORT, addr, &rxdata, 1, false);
// if acknowledged -> ret == number of bytes sent
if(ret > 0){
@@ -67,27 +34,38 @@ void bus_task() {
// scan bus for slaves
// send updates at regular intervals
await_init();
-
- int i = 0;
- uint8_t found[MAX_SLAVES];
- 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 = 0x01;
- // send data to found slave address
- write_i2c(found[i], &data, 1);
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+
+ // int i = 0;
+ // uint8_t found[MAX_SLAVES];
+ // init_addr_array(found, MAX_SLAVES);
+
+ while (true) {
+ vTaskDelay(9 / portTICK_PERIOD_MS);
+ pbdrv_i2c_send(0x69, (uint8_t *) "bbbbbbbb", 9);
- data = 0x02;
- write_i2c(found[i], &data, 1);
- // request update from slave addr at found[i]
- //write_i2c();
- }
+ // i2c_write_blocking(i2c0, 0x69, (uint8_t *) "bbbbbbbb", 9, false);
+ // pbdrv_i2c_recv(NULL, 0);
}
+
+ // 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();
+ // }
+ // }
}
+
diff --git a/main/i2c.h b/main/i2c.h
index 5ad5cfb..e873fae 100644
--- a/main/i2c.h
+++ b/main/i2c.h
@@ -5,40 +5,8 @@
#include <stdint.h>
#include <hardware/i2c.h>
-#define SDA_PIN 16
-#define SCL_PIN 17
-#define I2C_PORT i2c0
#define MAX_SLAVES 10
-/**
- * \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 looking for slave addresses and requesting updates */
void bus_task();
+
diff --git a/main/init.c b/main/init.c
index 90f0b1e..9297093 100644
--- a/main/init.c
+++ b/main/init.c
@@ -1,6 +1,6 @@
#include "config.h"
#include "init.h"
-#include "i2c.h"
+#include "drv/rp2040/mod.h"
#include <FreeRTOS.h>
#include <task.h>
@@ -32,6 +32,14 @@ static void init_wifi() {
// 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();
+ //printf("i2c setup\n");
+}
+
static void async_init() {
init_cyw34();
init_i2c();
diff --git a/main/main.c b/main/main.c
index 9fefed5..5d2abd1 100644
--- a/main/main.c
+++ b/main/main.c
@@ -13,10 +13,10 @@ void blink_task() {
await_init(); // `blink_task` uses GPIO
while (true) {
- cyw43_arch_gpio_put(CFG_LED_PIN, 0);
- vTaskDelay(250 / portTICK_PERIOD_MS);
cyw43_arch_gpio_put(CFG_LED_PIN, 1);
- vTaskDelay(250 / portTICK_PERIOD_MS);
+ vTaskDelay(50 / portTICK_PERIOD_MS);
+ cyw43_arch_gpio_put(CFG_LED_PIN, 0);
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
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;
+