A1-desk-board-selector.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include <sys/ioctl.h>
  2. #include <errno.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <linux/i2c.h>
  8. #include <linux/i2c-dev.h>
  9. #include <stdint.h>
  10. #include <stdbool.h>
  11. #include <fcntl.h>
  12. #include "miner.h"
  13. struct pcf8575_ctx {
  14. uint8_t addr;
  15. uint8_t p0;
  16. uint8_t p1;
  17. int file;
  18. uint8_t active_board;
  19. pthread_mutex_t lock;
  20. };
  21. static struct pcf8575_ctx board_ctx = { 0x27, 0xff, 0xff, -1, .active_board = 255,};
  22. #define UNUSED_BITS 0xe0
  23. #define SLEEP_MS_AFTER_CS 0
  24. static bool pcf8575_write(void)
  25. {
  26. union i2c_smbus_data data;
  27. data.byte = board_ctx.p1 | UNUSED_BITS;
  28. struct i2c_smbus_ioctl_data args;
  29. __s32 err;
  30. args.read_write = I2C_SMBUS_WRITE;
  31. args.command = board_ctx.p0 | UNUSED_BITS;
  32. args.size = I2C_SMBUS_BYTE_DATA;
  33. args.data = &data;
  34. err = ioctl(board_ctx.file, I2C_SMBUS, &args);
  35. if (err == -1) {
  36. fprintf(stderr,
  37. "Error: Failed to write: %s\n",
  38. strerror(errno));
  39. err = -errno;
  40. } else {
  41. applog(LOG_DEBUG, "written: 0x%02x, 0x%02x", board_ctx.p0, board_ctx.p1);
  42. // usleep(25000);
  43. cgsleep_ms(SLEEP_MS_AFTER_CS);
  44. }
  45. return err == 0;
  46. }
  47. void lock_board_selector(void)
  48. {
  49. // applog(LOG_WARNING, "lock_board_selector()");
  50. mutex_lock(&board_ctx.lock);
  51. }
  52. void unlock_board_selector(void)
  53. {
  54. // applog(LOG_WARNING, "unlock_board_selector()");
  55. mutex_unlock(&board_ctx.lock);
  56. }
  57. bool a1_board_selector_init(void)
  58. {
  59. mutex_init(&board_ctx.lock);
  60. applog(LOG_WARNING, "a1_board_selector_init()");
  61. board_ctx.file = open("/dev/i2c-1", O_RDWR);
  62. if (board_ctx.file < 0) {
  63. fprintf(stderr,
  64. "Error: Could not open i2c-1: %s\n",
  65. board_ctx.addr, strerror(errno));
  66. return false;
  67. }
  68. if (ioctl(board_ctx.file, I2C_SLAVE, board_ctx.addr) < 0) {
  69. fprintf(stderr,
  70. "Error: Could not set address to 0x%02x: %s\n",
  71. board_ctx.addr, strerror(errno));
  72. return false;
  73. }
  74. return pcf8575_write();
  75. }
  76. void a1_board_selector_exit(void)
  77. {
  78. close(board_ctx.file);
  79. board_ctx.file = -1;
  80. }
  81. bool a1_board_selector_select_board(uint8_t board)
  82. {
  83. if (board > 7)
  84. return false;
  85. // applog(LOG_WARNING, "board_selector_select_board(%d)", board);
  86. lock_board_selector();
  87. if (board_ctx.active_board == board)
  88. return true;
  89. board_ctx.active_board = board;
  90. board_ctx.p0 = 1 << board_ctx.active_board;
  91. board_ctx.p1 = 0xff;
  92. bool retval = pcf8575_write();
  93. return retval;
  94. }
  95. static bool __board_selector_reset(void)
  96. {
  97. board_ctx.p1 = ~board_ctx.p0;
  98. if (!pcf8575_write())
  99. return false;
  100. usleep(1000000);
  101. board_ctx.p1 = 0xff;
  102. if (!pcf8575_write())
  103. return false;
  104. usleep(1000000);
  105. return true;
  106. }
  107. // we assume we are already holding the mutex
  108. bool a1_board_selector_reset_board(void)
  109. {
  110. // lock_board_selector();
  111. bool retval = __board_selector_reset();
  112. // unlock_board_selector();
  113. return retval;
  114. }
  115. bool a1_board_selector_reset_all_boards(void)
  116. {
  117. lock_board_selector();
  118. board_ctx.p1 = 0;
  119. bool retval = __board_selector_reset();
  120. unlock_board_selector();
  121. return retval;
  122. }
  123. #if 0
  124. int main(void)
  125. {
  126. if (init_pcf8575(&board_ctx)) {
  127. if (!pcf8575_write(&g_ctx)) {
  128. fprintf(stderr,
  129. "Error: Failed to write: %s\n",
  130. strerror(errno));
  131. }
  132. a1_board_selector_exit(&g_ctx);
  133. }
  134. return 0;
  135. }
  136. #endif
  137. /////////////////////////////////////////////////////////////////////////////