#include #include #include #include #include #include #include #include #include #include #include #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 /////////////////////////////////////////////////////////////////////////////