i2c-slave-eeprom.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include "FreeRTOS.h"
  2. #include "board.h"
  3. #include "chip.h"
  4. #ifdef I2C_EEPROM_SLAVE_DEMO
  5. #if !defined(I2C0_SLAVE_MODE) && !defined(I2C1_SLAVE_MODE)
  6. #error "i2c eeprom slave demo needs a slave mode i2c dev"
  7. #endif
  8. #define I2C_EEPROM_24C02_ADDR 0x50
  9. #define I2C_EEPROM_24C02_SIZE 256
  10. struct eeprom_data {
  11. bool first_write;
  12. u8 buffer_idx;
  13. u8 buffer[];
  14. };
  15. static struct eeprom_data *g_eeprom = NULL;
  16. static struct i2c_adapter *g_adap = NULL;
  17. static int i2c_slave_eeprom_slave_cb(struct i2c_adapter *adap,
  18. enum i2c_slave_event event, u8 *val)
  19. {
  20. struct eeprom_data *eeprom = g_eeprom;
  21. switch (event) {
  22. case I2C_SLAVE_WRITE_RECEIVED:
  23. if (eeprom->first_write) {
  24. eeprom->buffer_idx = *val;
  25. eeprom->first_write = false;
  26. } else {
  27. eeprom->buffer[eeprom->buffer_idx++] = *val;
  28. }
  29. break;
  30. case I2C_SLAVE_READ_REQUESTED:
  31. *val = eeprom->buffer[eeprom->buffer_idx++];
  32. /*
  33. * Do not increment buffer_idx here, because we don't know if
  34. * this byte will be actually used. Read Linux I2C slave docs
  35. * for details.
  36. */
  37. break;
  38. case I2C_SLAVE_STOP:
  39. case I2C_SLAVE_WRITE_REQUESTED:
  40. eeprom->first_write = true;
  41. break;
  42. default:
  43. break;
  44. }
  45. return 0;
  46. }
  47. int i2c_slave_eeprom_init(void)
  48. {
  49. struct eeprom_data *eeprom;
  50. int ret;
  51. unsigned size = I2C_EEPROM_24C02_SIZE;
  52. struct i2c_adapter *adap = NULL;
  53. eeprom = pvPortMalloc(sizeof(struct eeprom_data) + size);
  54. if (!eeprom)
  55. return -ENOMEM;
  56. g_eeprom = eeprom;
  57. eeprom->first_write = true;
  58. #ifdef I2C0_SLAVE_MODE
  59. adap = i2c_open("i2c0");
  60. #else
  61. adap = i2c_open("i2c1");
  62. #endif
  63. if (!adap) {
  64. printf("%s open i2c fail.\n", __func__);
  65. vPortFree(eeprom);
  66. return -1;
  67. }
  68. g_adap = adap;
  69. ret = i2c_slave_register(adap, I2C_EEPROM_24C02_ADDR, i2c_slave_eeprom_slave_cb);
  70. if (ret) {
  71. return ret;
  72. }
  73. return 0;
  74. };
  75. int i2c_slave_eeprom_uninit(void)
  76. {
  77. if (g_adap)
  78. i2c_slave_unregister(g_adap);
  79. if (g_eeprom)
  80. vPortFree(g_eeprom);
  81. return 0;
  82. }
  83. #endif