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