diff --git a/dev/i2c-comms/CMakeLists.txt b/dev/i2c-comms/CMakeLists.txt index b961952..2fd69ae 100644 --- a/dev/i2c-comms/CMakeLists.txt +++ b/dev/i2c-comms/CMakeLists.txt @@ -34,7 +34,10 @@ pico_enable_stdio_usb(pico_i2c 1) # Add the standard library to the build target_link_libraries(pico_i2c - pico_stdlib) + pico_stdlib + pico_i2c_slave + hardware_i2c + ) # Add the standard include files to the build target_include_directories(pico_i2c PRIVATE diff --git a/dev/i2c-comms/pi_i2c.py b/dev/i2c-comms/pi_i2c.py index a4b07c7..c912136 100644 --- a/dev/i2c-comms/pi_i2c.py +++ b/dev/i2c-comms/pi_i2c.py @@ -4,7 +4,7 @@ I2C_PRIM = 0x0703 -# open i2c devices +# open i2c devices (sudo apt install i2c-tools) i2c_fd = os.open("/dev/i2c-1", os.O_RDWR) # set the i2c address of pico @@ -13,6 +13,17 @@ # send data to pico data = [0x01, 0x02, 0x03] # example data -while (True): - os.write(i2c_fd, bytes(data)) - time.sleep(1) +while True: + try: + os.write(i2c_fd, bytes(data)) + time.sleep(0.02) + print("Sent data to Pico: ", list(data)) + except OSError: + print("Remote I/O Error") + # read data from pico + try: + incoming_data = os.read(i2c_fd, 3) # read 3 bytes + time.sleep(0.02) + print("Received data from Pico: ", list(incoming_data)) + except TimeoutError: + print("Timeout Error") diff --git a/dev/i2c-comms/pi_spi.c b/dev/i2c-comms/pi_spi.c new file mode 100644 index 0000000..6de7862 --- /dev/null +++ b/dev/i2c-comms/pi_spi.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include + +#define SPI_DEVICE "/dev/spidev0.0" +#define SPI_SPEED 1000000 // 1MHz + +int main() { + int spi_fd; + unsigned char tx_data[] = {0xAA, 0xBB, 0xCC, 0xDD}; + unsigned char rx_data[sizeof(tx_data)]; + + spi_fd = open(SPI_DEVICE, O_RDWR); + if (spi_fd < 0) { + perror("Error opening SPI device"); + return -1; + } + + int mode = SPI_MODE_0; + if (ioctl(spi_fd, SPI_IOC_WR_MODE, &mode) == -1) { + perror("Error setting SPI mode"); + return -1; + } + + if (ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &SPI_SPEED) == -1) { + perror("Error setting SPI speed"); + return -1; + } + + struct spi_ioc_transfer transfer = { + .tx_buf = (unsigned long)tx_data, + .rx_buf = (unsigned long)rx_data, + .len = sizeof(tx_data), + .speed_hz = SPI_SPEED, + .bits_per_word = 8, + }; + + while (1) { + if (ioctl(spi_fd, SPI_IOC_MESSAGE(1), &transfer) == -1) { + perror("Error during SPI message transfer"); + return -1; + } + + printf("Received data: "); + for (int i = 0; i < sizeof(rx_data); i++) { + printf(" %02X", rx_data[i]); + } + printf("\n"); + sleep(1); + + } + close(spi_fd); + return 0; +} \ No newline at end of file diff --git a/dev/i2c-comms/pico_i2c.c b/dev/i2c-comms/pico_i2c.c index 948dc18..3880f90 100644 --- a/dev/i2c-comms/pico_i2c.c +++ b/dev/i2c-comms/pico_i2c.c @@ -1,32 +1,77 @@ #include -#include "pico/stdlib.h" -#include "hardware/i2c.h" +#include +#include +#include -int main() { +#ifndef PICO_DEFAULT_LED_PIN +#warning blink requires a board with a regular LED +#else +const uint LED_PIN = PICO_DEFAULT_LED_PIN; +#endif + +uint8_t outgoing_data[3] = {0x11, 0x12, 0x13}; // example data +uint8_t incoming_data[3]; +int data_index = 0; + +static void i2c_slave_handler(i2c_inst_t *i2c, i2c_slave_event_t event) +{ + switch (event) + { + case I2C_SLAVE_RECEIVE: // master has written some data + for (int i = 0; i < 3; i++) + { + if (incoming_data[i] == 0x00) + { + incoming_data[i] = i2c_read_byte_raw(i2c); + printf("Received data %d: 0x%02X\n ", i, incoming_data[i]); + gpio_put(LED_PIN, 1); + break; + } + } + break; + case I2C_SLAVE_REQUEST: // master is requesting data + i2c_write_byte_raw(i2c, outgoing_data[data_index]); + printf("Sent data %d: 0x%02X\n ", data_index, outgoing_data[data_index]); + gpio_put(LED_PIN, 0); + data_index++; + if (data_index > 2) + { + data_index = 0; + } + break; + case I2C_SLAVE_FINISH: // master has signalled Stop / Restart + data_index = 0; + for (int i = 0; i < 3; i++) + { + incoming_data[i] = 0x00; + } + break; + default: + break; + } +} + +int main() +{ stdio_init_all(); +#ifndef PICO_DEFAULT_LED_PIN +#warning blink requires a board with a regular LED +#else + gpio_init(LED_PIN); + gpio_set_dir(LED_PIN, GPIO_OUT); +#endif + // init i2c at 100kHz i2c_init(i2c0, 100 * 1000); gpio_set_function(0, GPIO_FUNC_I2C); gpio_set_function(1, GPIO_FUNC_I2C); - // i2c_pullup_en(i2c0, true); // set i2c address for pico - i2c_set_slave_mode(i2c0, true, 0x08); - // i2c_set_slave_address(i2c0, 0x08); // address should match pi code - - uint8_t data[3]; - - while(1) { - // read data from i2c_pi.py - i2c_read_blocking(i2c0, 0x08, data, 3, true); - - // process data - for (int i = 0; i < 3; i++) { - printf("Received data %d: 0x%02X\n ", i, data[i]); - } - } + i2c_slave_init(i2c0, 0x08, &i2c_slave_handler); - return 0; + while (1) + ; + return 0; } \ No newline at end of file diff --git a/dev/i2c-comms/pico_spi.c b/dev/i2c-comms/pico_spi.c new file mode 100644 index 0000000..2e7be5b --- /dev/null +++ b/dev/i2c-comms/pico_spi.c @@ -0,0 +1,32 @@ +#include +#include "pico/stdlib.h" +#include "hardware/spi.h" + +#define SPI_PORT spi0 +#define PIN_MISO 16 +#define PIN_CS 17 + +int main() { + stdio_init_all(); + + spi_init(SPI_PORT, 1000 * 1000); // init at 1MHz + gpio_set_function(PIN_MISO, GPIO_FUNC_SPI); // set pin to SPI mode + + gpi_init(PIN_CS); + gpio_set_dir(PIN_CS, GPIO_OUT); + + while (1) { + gpio_put(PIN_CS, 1); // set CS high to indiciate start of communication + uint8_t rx_data[4]; + spi_read_blocking(SPI_PORT, 0, rx_data, sizeof(rx_data)); // read data from pi + gpio_put(PIN_CS, 0); // set CS low to indicate end of communication + + printf("Received: "); + for (int i = 0; i < sizeof(rx_data); i++) { + printf(" %02X", rx_data[i]); + } + printf("\n"); + sleep_ms(1000); + } + return 0; +} \ No newline at end of file