diff --git a/master/src/main.c b/master/src/main.c index a143b31..914085c 100644 --- a/master/src/main.c +++ b/master/src/main.c @@ -12,7 +12,7 @@ #include #include -int main(void) +void main(void) { stdio_init_all(); @@ -20,19 +20,6 @@ int main(void) puts("STDIO INIT DONE"); - printf("Initialisation des broches\n"); - for(int i=0; i++; i<=28){ - if(gpio_get_function(i) == GPIO_FUNC_I2C){ - printf("Borche I2C : %d\n", i); - gpio_set_function(i, GPIO_FUNC_NULL); - } - } - - printf("%d et %d en I2C\n", I2C_MASTER_SDA_PIN, I2C_MASTER_SCL_PIN); - gpio_set_function(I2C_MASTER_SDA_PIN, GPIO_FUNC_I2C); - gpio_set_function(I2C_MASTER_SCL_PIN, GPIO_FUNC_I2C); - - i2c_master_init(); puts("I2C MASTER INIT DONE"); @@ -42,16 +29,14 @@ int main(void) while(true) { uint8_t data[] = {0x00, led_state}; - int ret = i2c_master_write(0x09, data, 2); + int ret = i2c_write_blocking(I2C_MASTER_INSTANCE, 0x09, data, 2, false); - if(ret = PICO_ERROR_GENERIC) + if(ret == PICO_ERROR_GENERIC) puts("I2C ERROR GENERIC"); else printf("Written %d bytes\n", ret); led_state = !led_state; - sleep_ms(50); + sleep_ms(1000); } - - return 0; } diff --git a/slave/CMakeLists.txt b/slave/CMakeLists.txt index 7c9c0b0..1e09b35 100644 --- a/slave/CMakeLists.txt +++ b/slave/CMakeLists.txt @@ -13,14 +13,13 @@ pico_sdk_init() add_executable(motion_controller src/main.c src/i2c_slave.c - src/i2c_buffer.c ) target_link_libraries(motion_controller - hardware_i2c - hardware_pwm - hardware_uart pico_stdlib + hardware_uart + hardware_i2c + pico_i2c_slave ) pico_enable_stdio_usb(motion_controller 1) diff --git a/slave/src/i2c_buffer.c b/slave/src/i2c_buffer.c deleted file mode 100644 index 913c395..0000000 --- a/slave/src/i2c_buffer.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "include/i2c_buffer.h" -#include - - -extern i2c_buffer_t i2c_buffer; - -void __not_in_flash_func(i2c_slave_buffer_handler)(i2c_slave_event_t event) -{ - switch(event) - { - case I2C_SLAVE_RECEIVE: // master has written some data - gpio_put(PICO_DEFAULT_LED_PIN, 1); - - if(!i2c_buffer.buffer_reg_written) - { - // writes always start with the memory address - i2c_buffer.buffer_reg = i2c_slave_read_byte(); - i2c_buffer.buffer_reg_written = true; - } - else - { - // save into memory - i2c_buffer.buffer[i2c_buffer.buffer_reg] = i2c_slave_read_byte(); - i2c_buffer.buffer_reg++; - } - break; - - case I2C_SLAVE_REQUEST: // master is requesting data - // load from memory - i2c_slave_write_byte(i2c_buffer.buffer[i2c_buffer.buffer_reg]); - i2c_buffer.buffer_reg++; - break; - - case I2C_SLAVE_FINISH: // master has signalled Stop / Restart - i2c_buffer.buffer_reg_written = false; - break; - - default: - break; - } -} diff --git a/slave/src/i2c_slave.c b/slave/src/i2c_slave.c index a68bf8b..b43da03 100644 --- a/slave/src/i2c_slave.c +++ b/slave/src/i2c_slave.c @@ -6,97 +6,67 @@ #include "include/i2c_slave.h" -#include -#include -#include "include/i2c_buffer.h" +#include +#include +#include "pico/i2c_slave.h" + #include -static bool transfer_in_progress; +extern i2c_buffer_t i2c_buffer; -static inline void finish_transfer(void) +void i2c_slave_buffer_handler(i2c_inst_t *i2c, i2c_slave_event_t event) { - if(transfer_in_progress) + switch(event) { - i2c_slave_buffer_handler(I2C_SLAVE_FINISH); - transfer_in_progress = false; + case I2C_SLAVE_RECEIVE: // master has written some data + if(!i2c_buffer.buffer_reg_written) + { + // writes always start with the memory address + i2c_buffer.buffer_reg = i2c_read_byte_raw(I2C_SLAVE_INSTANCE); + i2c_buffer.buffer_reg_written = true; + } + else + { + // save into memory + i2c_buffer.buffer[i2c_buffer.buffer_reg] = i2c_read_byte_raw(I2C_SLAVE_INSTANCE); + i2c_buffer.buffer_reg++; + } + break; + + case I2C_SLAVE_REQUEST: // master is requesting data + // load from memory + i2c_write_byte_raw(I2C_SLAVE_INSTANCE, i2c_buffer.buffer[i2c_buffer.buffer_reg]); + i2c_buffer.buffer_reg++; + break; + + case I2C_SLAVE_FINISH: // master has signalled Stop / Restart + i2c_buffer.buffer_reg_written = false; + break; + + default: + break; } } -static void __not_in_flash_func(i2c_slave_irq_handler)(void) -{ - i2c_hw_t *hw = i2c_get_hw(I2C_SLAVE_INSTANCE); - - uint32_t intr_stat = hw->intr_stat; - - if(intr_stat == 0) - { - return; - } - - if(intr_stat & I2C_IC_INTR_STAT_R_TX_ABRT_BITS) - { - hw->clr_tx_abrt; - finish_transfer(); - } - - if(intr_stat & I2C_IC_INTR_STAT_R_START_DET_BITS) - { - hw->clr_start_det; - finish_transfer(); - } - - if(intr_stat & I2C_IC_INTR_STAT_R_STOP_DET_BITS) - { - hw->clr_stop_det; - i2c_slave_buffer_handler(I2C_SLAVE_RECEIVE); - finish_transfer(); - } - - if(intr_stat & I2C_IC_INTR_STAT_R_RX_FULL_BITS) - { - transfer_in_progress = true; - i2c_slave_buffer_handler(I2C_SLAVE_RECEIVE); - } - - if(intr_stat & I2C_IC_INTR_STAT_R_RD_REQ_BITS) - { - hw->clr_rd_req; - transfer_in_progress = true; - i2c_slave_buffer_handler(I2C_SLAVE_REQUEST); - } -} - -void i2c_slave_init(void) +void init_i2c_slave(void) { // Init GPIO pins + gpio_init(I2C_SLAVE_SDA_PIN); + gpio_init(I2C_SLAVE_SCL_PIN); gpio_set_function(I2C_SLAVE_SDA_PIN, GPIO_FUNC_I2C); gpio_set_function(I2C_SLAVE_SCL_PIN, GPIO_FUNC_I2C); - // Note: The I2C slave does clock stretching implicitly after a RD_REQ, while the Tx FIFO is empty. - // There is also an option to enable clock stretching while the Rx FIFO is full, but we leave it - // disabled since the Rx FIFO should never fill up (unless i2c_slave.handler() is way too slow). - i2c_set_slave_mode(I2C_SLAVE_INSTANCE, true, I2C_SLAVE_ADDRESS); - - i2c_hw_t *hw = i2c_get_hw(I2C_SLAVE_INSTANCE); - // unmask necessary interrupts - hw->intr_mask = I2C_IC_INTR_MASK_M_RX_FULL_BITS | I2C_IC_INTR_MASK_M_RD_REQ_BITS | I2C_IC_RAW_INTR_STAT_TX_ABRT_BITS | I2C_IC_INTR_MASK_M_STOP_DET_BITS | I2C_IC_INTR_MASK_M_START_DET_BITS; - - // enable interrupt for current core - uint num = I2C0_IRQ + i2c_get_index(I2C_SLAVE_INSTANCE); - irq_set_exclusive_handler(num, i2c_slave_irq_handler); - irq_set_enabled(num, true); + i2c_init(I2C_SLAVE_INSTANCE, 0); + // New SDK method to init i2c slave + i2c_slave_init(I2C_SLAVE_INSTANCE, I2C_SLAVE_ADDRESS, &i2c_slave_buffer_handler); } -void i2c_slave_deinit(void) +void deinit_i2c_slave(void) { - uint num = I2C0_IRQ + i2c_get_index(I2C_SLAVE_INSTANCE); - irq_set_enabled(num, false); - irq_remove_handler(num, i2c_slave_irq_handler); + // Reset GPIO pins + gpio_set_function(I2C_SLAVE_SDA_PIN, GPIO_FUNC_NULL); + gpio_set_function(I2C_SLAVE_SCL_PIN, GPIO_FUNC_NULL); - i2c_set_slave_mode(I2C_SLAVE_INSTANCE, false, 0); - - transfer_in_progress = false; - - i2c_hw_t *hw = i2c_get_hw(I2C_SLAVE_INSTANCE); - hw->intr_mask = I2C_IC_INTR_MASK_RESET; + // New SDK method to reset i2c slave + i2c_slave_deinit(I2C_SLAVE_INSTANCE); } diff --git a/slave/src/include/i2c_buffer.h b/slave/src/include/i2c_buffer.h deleted file mode 100644 index 8bfb859..0000000 --- a/slave/src/include/i2c_buffer.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef I2C_BUFFER_H -#define I2C_BUFFER_H - -#include -#include "i2c_slave.h" - -typedef struct i2c_buffer_t { - uint8_t buffer[256]; - uint8_t buffer_reg; - bool buffer_reg_written; -} i2c_buffer_t; - -// I2c slave buffer handler for writing and reading data to the buffer -void __not_in_flash_func(i2c_slave_buffer_handler)(i2c_slave_event_t event); -// Update motors from the data in the i2c buffer -void update_motors_from_buffer(void); -// Update servo motors from the data in the i2c buffer -void update_servo_motors_from_buffer(void); - -#endif // I2C_BUFFER_H \ No newline at end of file diff --git a/slave/src/include/i2c_slave.h b/slave/src/include/i2c_slave.h index 49681e4..017d4bd 100644 --- a/slave/src/include/i2c_slave.h +++ b/slave/src/include/i2c_slave.h @@ -14,30 +14,15 @@ #define I2C_SLAVE_INSTANCE i2c0 #define I2C_SLAVE_ADDRESS 0x09 -typedef enum i2c_slave_event_t { - I2C_SLAVE_RECEIVE, // < Data from master is available for reading. Slave must read from Rx FIFO. - I2C_SLAVE_REQUEST, // < Master is requesting data. Slave must write into Tx FIFO. - I2C_SLAVE_FINISH, // < Master has sent a Stop or Restart signal. Slave may prepare for the next transfer. -} i2c_slave_event_t; +typedef struct i2c_buffer_t { + uint8_t buffer[256]; + uint8_t buffer_reg; + bool buffer_reg_written; +} i2c_buffer_t; -static inline uint8_t i2c_slave_read_byte(void) -{ - i2c_hw_t *hw = i2c_get_hw(I2C_SLAVE_INSTANCE); - assert(hw->status & I2C_IC_STATUS_RFNE_BITS); // Rx FIFO must not be empty - return (uint8_t)hw->data_cmd; -} - -static inline void i2c_slave_write_byte(uint8_t value) -{ - i2c_hw_t *hw = i2c_get_hw(I2C_SLAVE_INSTANCE); - assert(hw->status & I2C_IC_STATUS_TFNF_BITS); // Tx FIFO must not be full - hw->data_cmd = value; -} - -// Init I2C with default parameters -void i2c_slave_init(void); - -// Deinit I2C with default parameters -void i2c_slave_deinit(void); +// Init i2c slave with default parameters +void init_i2c_slave(void); +// Deinit i2c slave +void deinit_i2c_slave(void); #endif // I2C_SLAVE_H \ No newline at end of file diff --git a/slave/src/main.c b/slave/src/main.c index 424439e..0a37250 100644 --- a/slave/src/main.c +++ b/slave/src/main.c @@ -9,9 +9,8 @@ \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include -#include "include/i2c_slave.h" -#include "include/i2c_buffer.h" #include +#include "include/i2c_slave.h" i2c_buffer_t i2c_buffer; @@ -23,20 +22,17 @@ int main(void) puts("STDIO INIT ALL DONE"); - i2c_slave_init(); + init_i2c_slave(); puts("SLAVE INIT DONE"); gpio_init(PICO_DEFAULT_LED_PIN); gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); - puts("DEFAULT LED INIT DONE"); - while(true) { - gpio_put(PICO_DEFAULT_LED_PIN, 0); - printf("BUFFER[0]:%d\n", i2c_buffer.buffer[0]); - sleep_ms(300); + gpio_put(PICO_DEFAULT_LED_PIN, i2c_buffer.buffer[2]); + sleep_ms(10); } return 0;