i2c_slave_sample.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include <stdio.h>
  2. #include "pico/stdlib.h"
  3. #include "hardware/i2c.h"
  4. #include "hardware/adc.h"
  5. #include "pico/i2c_slave.h"
  6. #define I2C_SDA 8
  7. #define I2C_SCL 9
  8. #define I2C_SLAVE_ADDR 0x41
  9. #define CMD_NONE 0
  10. #define CMD_GET_VOLT 1
  11. #define CMD_GET_FACTOR 2
  12. #define CMD_GET_RAW 3
  13. #define CMD_UNKNOWN 4
  14. #define ADC_INPUT_PIN 26
  15. #define ADC_CH 0
  16. #define ADC_FACTOR 10000
  17. #define ADC_REF 33000
  18. bool i2c_slave_request(i2c_inst_t *i2c, int cmd)
  19. {
  20. bool rval = false;
  21. switch(cmd){
  22. case CMD_NONE:
  23. // 適当に0を返しておく
  24. uint8_t data[2] = {0, 0};
  25. i2c_write_raw_blocking(i2c, data, 2);
  26. rval = true;
  27. break;
  28. case CMD_GET_VOLT:
  29. case CMD_GET_RAW:
  30. uint16_t value;
  31. uint32_t volt;
  32. adc_select_input(ADC_CH);
  33. value = adc_read();
  34. volt = value * 33000 / 4096;
  35. // MSB First
  36. if(cmd == CMD_GET_VOLT) {
  37. value = volt;
  38. }
  39. i2c_write_raw_blocking(i2c, (uint8_t *)&value, sizeof(uint16_t));
  40. rval = true;
  41. break;
  42. case CMD_GET_FACTOR:
  43. uint16_t fact = ADC_FACTOR;
  44. i2c_write_raw_blocking(i2c, (uint8_t *)&fact, sizeof(uint16_t));
  45. rval = true;
  46. break;
  47. default:
  48. rval = false;
  49. }
  50. return rval;
  51. }
  52. static void i2c_slave_callback(i2c_inst_t *i2c, i2c_slave_event_t event)
  53. {
  54. static int slave_cmd = CMD_NONE;
  55. switch(event) {
  56. // マスターからのデータ受信
  57. case I2C_SLAVE_RECEIVE:
  58. // マスターからの1バイトを取り出す
  59. uint8_t rdata = i2c_read_byte_raw(i2c);
  60. if(rdata < CMD_UNKNOWN) {
  61. slave_cmd = rdata; // コマンド更新
  62. }
  63. break;
  64. // マスターからデータ要求
  65. case I2C_SLAVE_REQUEST:
  66. bool r = i2c_slave_request(i2c, slave_cmd);
  67. if(r)
  68. slave_cmd = CMD_NONE;
  69. break;
  70. // ストップまたはRepeated Start Condition
  71. case I2C_SLAVE_FINISH:
  72. break;
  73. }
  74. }
  75. int main()
  76. {
  77. stdio_init_all();
  78. // I2C Initialisation. Using it at 400Khz.
  79. i2c_init(i2c0, 100*1000);
  80. gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
  81. gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
  82. gpio_disable_pulls(I2C_SDA);
  83. gpio_disable_pulls(I2C_SCL);
  84. adc_init();
  85. adc_gpio_init(ADC_INPUT_PIN);
  86. i2c_slave_init(i2c0, I2C_SLAVE_ADDR, i2c_slave_callback);
  87. while (true) {
  88. tight_loop_contents();
  89. }
  90. }