diff options
-rw-r--r-- | main/CMakeLists.txt | 2 | ||||
-rw-r--r-- | main/i2c.c | 93 | ||||
-rw-r--r-- | main/i2c.h | 44 | ||||
-rw-r--r-- | main/init.c | 7 | ||||
-rw-r--r-- | main/main.c | 4 |
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(); } |