pca9505.c (3699B)
1 // Copyright 2022 nirim000 2 // SPDX-License-Identifier: GPL-2.0-or-later 3 4 #include "i2c_master.h" 5 #include "pca9505.h" 6 7 #include "debug.h" 8 9 #define SLAVE_TO_ADDR(n) (n << 1) 10 #define TIMEOUT 100 11 12 enum { 13 CMD_INPUT_0 = 0, 14 CMD_INPUT_1, 15 CMD_INPUT_2, 16 CMD_INPUT_3, 17 CMD_INPUT_4, 18 CMD_OUTPUT_0 = 8, 19 CMD_OUTPUT_1, 20 CMD_OUTPUT_2, 21 CMD_OUTPUT_3, 22 CMD_OUTPUT_4, 23 CMD_INVERSION_0 = 16, 24 CMD_INVERSION_1, 25 CMD_INVERSION_2, 26 CMD_INVERSION_3, 27 CMD_INVERSION_4, 28 CMD_CONFIG_0 = 24, 29 CMD_CONFIG_1, 30 CMD_CONFIG_2, 31 CMD_CONFIG_3, 32 CMD_CONFIG_4, 33 }; 34 35 void pca9505_init(uint8_t slave_addr) { 36 static uint8_t s_init = 0; 37 if (!s_init) { 38 i2c_init(); 39 40 s_init = 1; 41 } 42 43 // TODO: could check device connected 44 } 45 46 bool pca9505_set_config(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) { 47 uint8_t addr = SLAVE_TO_ADDR(slave_addr); 48 uint8_t cmd = 0; 49 switch (port) { 50 case 0: 51 cmd = CMD_CONFIG_0; 52 break; 53 case 1: 54 cmd = CMD_CONFIG_1; 55 break; 56 case 2: 57 cmd = CMD_CONFIG_2; 58 break; 59 case 3: 60 cmd = CMD_CONFIG_3; 61 break; 62 case 4: 63 cmd = CMD_CONFIG_4; 64 break; 65 } 66 67 i2c_status_t ret = i2c_write_register(addr, cmd, &conf, sizeof(conf), TIMEOUT); 68 if (ret != I2C_STATUS_SUCCESS) { 69 print("pca9505_set_config::FAILED\n"); 70 return false; 71 } 72 73 return true; 74 } 75 76 bool pca9505_set_polarity(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) { 77 uint8_t addr = SLAVE_TO_ADDR(slave_addr); 78 uint8_t cmd = 0; 79 switch (port) { 80 case 0: 81 cmd = CMD_INVERSION_0; 82 break; 83 case 1: 84 cmd = CMD_INVERSION_1; 85 break; 86 case 2: 87 cmd = CMD_INVERSION_2; 88 break; 89 case 3: 90 cmd = CMD_INVERSION_3; 91 break; 92 case 4: 93 cmd = CMD_INVERSION_4; 94 break; 95 } 96 97 i2c_status_t ret = i2c_write_register(addr, cmd, &conf, sizeof(conf), TIMEOUT); 98 if (ret != I2C_STATUS_SUCCESS) { 99 print("pca9505_set_polarity::FAILED\n"); 100 return false; 101 } 102 103 return true; 104 } 105 106 bool pca9505_set_output(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) { 107 uint8_t addr = SLAVE_TO_ADDR(slave_addr); 108 uint8_t cmd = 0; 109 switch (port) { 110 case 0: 111 cmd = CMD_OUTPUT_0; 112 break; 113 case 1: 114 cmd = CMD_OUTPUT_1; 115 break; 116 case 2: 117 cmd = CMD_OUTPUT_2; 118 break; 119 case 3: 120 cmd = CMD_OUTPUT_3; 121 break; 122 case 4: 123 cmd = CMD_OUTPUT_4; 124 break; 125 } 126 127 i2c_status_t ret = i2c_write_register(addr, cmd, &conf, sizeof(conf), TIMEOUT); 128 if (ret != I2C_STATUS_SUCCESS) { 129 print("pca9505_set_output::FAILED\n"); 130 return false; 131 } 132 133 return true; 134 } 135 136 bool pca9505_read_pins(uint8_t slave_addr, pca9505_port_t port, uint8_t* out) { 137 uint8_t addr = SLAVE_TO_ADDR(slave_addr); 138 uint8_t cmd = 0; 139 switch (port) { 140 case 0: 141 cmd = CMD_INPUT_0; 142 break; 143 case 1: 144 cmd = CMD_INPUT_1; 145 break; 146 case 2: 147 cmd = CMD_INPUT_2; 148 break; 149 case 3: 150 cmd = CMD_INPUT_3; 151 break; 152 case 4: 153 cmd = CMD_INPUT_4; 154 break; 155 } 156 157 i2c_status_t ret = i2c_read_register(addr, cmd, out, sizeof(uint8_t), TIMEOUT); 158 if (ret != I2C_STATUS_SUCCESS) { 159 print("pca9505_read_pins::FAILED\n"); 160 return false; 161 } 162 163 return true; 164 }