#include #include "pico/stdlib.h" #include "hardware/i2c.h" #include "hardware/adc.h" #include "pico/i2c_slave.h" #define I2C_SDA 8 #define I2C_SCL 9 #define I2C_SLAVE_ADDR 0x41 #define CMD_NONE 0 #define CMD_GET_VOLT 1 #define CMD_GET_FACTOR 2 #define CMD_GET_RAW 3 #define CMD_UNKNOWN 4 #define ADC_INPUT_PIN 26 #define ADC_CH 0 #define ADC_FACTOR 10000 #define ADC_REF 33000 bool i2c_slave_request(i2c_inst_t *i2c, int cmd) { bool rval = false; switch(cmd){ case CMD_NONE: // 適当に0を返しておく uint8_t data[2] = {0, 0}; i2c_write_raw_blocking(i2c, data, 2); rval = true; break; case CMD_GET_VOLT: case CMD_GET_RAW: uint16_t value; uint32_t volt; adc_select_input(ADC_CH); value = adc_read(); volt = value * 33000 / 4096; // MSB First if(cmd == CMD_GET_VOLT) { value = volt; } i2c_write_raw_blocking(i2c, (uint8_t *)&value, sizeof(uint16_t)); rval = true; break; case CMD_GET_FACTOR: uint16_t fact = ADC_FACTOR; i2c_write_raw_blocking(i2c, (uint8_t *)&fact, sizeof(uint16_t)); rval = true; break; default: rval = false; } return rval; } static void i2c_slave_callback(i2c_inst_t *i2c, i2c_slave_event_t event) { static int slave_cmd = CMD_NONE; switch(event) { // マスターからのデータ受信 case I2C_SLAVE_RECEIVE: // マスターからの1バイトを取り出す uint8_t rdata = i2c_read_byte_raw(i2c); if(rdata < CMD_UNKNOWN) { slave_cmd = rdata; // コマンド更新 } break; // マスターからデータ要求 case I2C_SLAVE_REQUEST: bool r = i2c_slave_request(i2c, slave_cmd); if(r) slave_cmd = CMD_NONE; break; // ストップまたはRepeated Start Condition case I2C_SLAVE_FINISH: break; } } int main() { stdio_init_all(); // I2C Initialisation. Using it at 400Khz. i2c_init(i2c0, 100*1000); gpio_set_function(I2C_SDA, GPIO_FUNC_I2C); gpio_set_function(I2C_SCL, GPIO_FUNC_I2C); gpio_disable_pulls(I2C_SDA); gpio_disable_pulls(I2C_SCL); adc_init(); adc_gpio_init(ADC_INPUT_PIN); i2c_slave_init(i2c0, I2C_SLAVE_ADDR, i2c_slave_callback); while (true) { tight_loop_contents(); } }