123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- #include <stdio.h>
- #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();
- if(cmd == CMD_GET_VOLT) {
- // 3.3V ref, 12-bit ADC(0-4095)
- value = (uint32_t)value * ADC_REF / 4095;
- }
- // RP2040はリトルエンディアンのため、LSBから送信される
- 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 100Khz.
- 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();
- }
- }
|