//Exemplo 19
// Configuração Básica da I2C no RP2040
//Leitura de dados com interrupção

#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "hardware/irq.h"
#include <stdio.h>

#define I2C_SLAVE_ADDRESS 0x42 // Endereço I2C do dispositivo escravo
#define BUFFER_SIZE 16
uint8_t rx_buffer[BUFFER_SIZE]; // Buffer para armazenar os dados recebidos
volatile int rx_index = 0;

// Função de callback para tratar a interrupção da I2C
void i2c0_irq_handler() {
  while (i2c_get_read_available(i2c0)) { // Verifica se há dados disponíveis
    if (rx_index < BUFFER_SIZE) {
      rx_buffer[rx_index++] = i2c_get_hw(i2c0)->data_cmd; // Lê o dado recebido
    }
  }
}

int main() {
  stdio_init_all();

  // Inicializa a I2C0 no modo escravo com endereço definido
  i2c_init(i2c0, 100 * 1000); // Inicializa a I2C a 100kHz
  i2c_set_slave_mode(i2c0, true, I2C_SLAVE_ADDRESS);

  // Configura os pinos SDA e SCL
  gpio_set_function(4, GPIO_FUNC_I2C); // SDA
  gpio_set_function(5, GPIO_FUNC_I2C); // SCL
  gpio_pull_up(4);
  gpio_pull_up(5);

  // Configura interrupção e máscara
  irq_set_exclusive_handler(I2C0_IRQ, i2c0_irq_handler);
  irq_set_enabled(I2C0_IRQ, true);

  i2c_get_hw(i2c0)->intr_mask = I2C_IC_INTR_MASK_M_RX_FULL_BITS;

  while (true) {
    printf("Loop ativo\n");
    if (rx_index > 0) {
      printf("Dados recebidos: ");
      for (int i = 0; i < rx_index; i++) {
        printf("%02x ", rx_buffer[i]);
      }
      printf("\n");
      rx_index = 0; // Reseta o índice após processar os dados
    }
    sleep_ms(2000);
  }

  return 0;
}