123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- #include <sys/ioctl.h>
- #include <errno.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <linux/i2c.h>
- #include <linux/i2c-dev.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include <fcntl.h>
- #include "miner.h"
- struct pcf8575_ctx {
- uint8_t addr;
- uint8_t p0;
- uint8_t p1;
- int file;
- uint8_t active_board;
- pthread_mutex_t lock;
- };
- static struct pcf8575_ctx board_ctx = { 0x27, 0xff, 0xff, -1, .active_board = 255,};
- #define UNUSED_BITS 0xe0
- #define SLEEP_MS_AFTER_CS 0
- static bool pcf8575_write(void)
- {
- union i2c_smbus_data data;
- data.byte = board_ctx.p1 | UNUSED_BITS;
- struct i2c_smbus_ioctl_data args;
- __s32 err;
- args.read_write = I2C_SMBUS_WRITE;
- args.command = board_ctx.p0 | UNUSED_BITS;
- args.size = I2C_SMBUS_BYTE_DATA;
- args.data = &data;
- err = ioctl(board_ctx.file, I2C_SMBUS, &args);
- if (err == -1) {
- fprintf(stderr,
- "Error: Failed to write: %s\n",
- strerror(errno));
- err = -errno;
- } else {
- applog(LOG_DEBUG, "written: 0x%02x, 0x%02x", board_ctx.p0, board_ctx.p1);
- // usleep(25000);
- cgsleep_ms(SLEEP_MS_AFTER_CS);
- }
- return err == 0;
- }
- void lock_board_selector(void)
- {
- // applog(LOG_WARNING, "lock_board_selector()");
- mutex_lock(&board_ctx.lock);
- }
- void unlock_board_selector(void)
- {
- // applog(LOG_WARNING, "unlock_board_selector()");
- mutex_unlock(&board_ctx.lock);
- }
- bool a1_board_selector_init(void)
- {
- mutex_init(&board_ctx.lock);
- applog(LOG_WARNING, "a1_board_selector_init()");
- board_ctx.file = open("/dev/i2c-1", O_RDWR);
- if (board_ctx.file < 0) {
- fprintf(stderr,
- "Error: Could not open i2c-1: %s\n",
- board_ctx.addr, strerror(errno));
- return false;
- }
- if (ioctl(board_ctx.file, I2C_SLAVE, board_ctx.addr) < 0) {
- fprintf(stderr,
- "Error: Could not set address to 0x%02x: %s\n",
- board_ctx.addr, strerror(errno));
- return false;
- }
- return pcf8575_write();
- }
- void a1_board_selector_exit(void)
- {
- close(board_ctx.file);
- board_ctx.file = -1;
- }
- bool a1_board_selector_select_board(uint8_t board)
- {
- if (board > 7)
- return false;
- // applog(LOG_WARNING, "board_selector_select_board(%d)", board);
- lock_board_selector();
- if (board_ctx.active_board == board)
- return true;
- board_ctx.active_board = board;
- board_ctx.p0 = 1 << board_ctx.active_board;
- board_ctx.p1 = 0xff;
- bool retval = pcf8575_write();
- return retval;
- }
- static bool __board_selector_reset(void)
- {
- board_ctx.p1 = ~board_ctx.p0;
- if (!pcf8575_write())
- return false;
- usleep(1000000);
- board_ctx.p1 = 0xff;
- if (!pcf8575_write())
- return false;
- usleep(1000000);
- return true;
- }
- // we assume we are already holding the mutex
- bool a1_board_selector_reset_board(void)
- {
- // lock_board_selector();
- bool retval = __board_selector_reset();
- // unlock_board_selector();
- return retval;
- }
- bool a1_board_selector_reset_all_boards(void)
- {
- lock_board_selector();
- board_ctx.p1 = 0;
- bool retval = __board_selector_reset();
- unlock_board_selector();
- return retval;
- }
- #if 0
- int main(void)
- {
- if (init_pcf8575(&board_ctx)) {
- if (!pcf8575_write(&g_ctx)) {
- fprintf(stderr,
- "Error: Failed to write: %s\n",
- strerror(errno));
- }
- a1_board_selector_exit(&g_ctx);
- }
- return 0;
- }
- #endif
- /////////////////////////////////////////////////////////////////////////////
|