aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main/CMakeLists.txt2
-rw-r--r--main/i2c.c93
-rw-r--r--main/i2c.h44
-rw-r--r--main/init.c7
-rw-r--r--main/main.c4
5 files changed, 146 insertions, 4 deletions
diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt
index 90ca8e3..30685a4 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
puzbus
diff --git a/main/i2c.c b/main/i2c.c
new file mode 100644
index 0000000..b324124
--- /dev/null
+++ b/main/i2c.c
@@ -0,0 +1,93 @@
+#include "i2c.h"
+#include "init.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;
+ 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_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 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);
+
+ 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
new file mode 100644
index 0000000..5ad5cfb
--- /dev/null
+++ b/main/i2c.h
@@ -0,0 +1,44 @@
+#pragma once
+// https://github.com/raspberrypi/pico-examples/tree/master/i2c
+
+#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
+
+/**
+ * \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 dcd3d54..08177c7 100644
--- a/main/init.c
+++ b/main/init.c
@@ -1,5 +1,6 @@
#include "config.h"
#include "init.h"
+#include "i2c.h"
#include <FreeRTOS.h>
#include <task.h>
@@ -23,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");
@@ -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);
diff --git a/main/main.c b/main/main.c
index 73b6708..19dd3cd 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
@@ -23,7 +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) 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();
}