1 /* 2 * Author: Henry Bruce <henry.bruce (at) intel.com> 3 * Copyright (c) 2014 Intel Corporation. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <unistd.h> 29 #include "mraa/i2c.h" 30 31 #include "mraa_internal_types.h" 32 33 extern mraa_board_t* plat; 34 35 void 36 print_version() 37 { 38 fprintf(stdout, "Version %s on %s", mraa_get_version(), mraa_get_platform_name()); 39 if (plat != NULL && plat->sub_platform != NULL) 40 fprintf(stdout, " with %s", plat->sub_platform->platform_name); 41 fprintf(stdout, "\n"); 42 } 43 44 void 45 print_help() 46 { 47 fprintf(stdout, "version Get mraa version and board name\n"); 48 fprintf(stdout, "list List available busses\n"); 49 fprintf(stdout, "detect bus List detected devices on specified bus\n"); 50 fprintf(stdout, "get bus device reg Get value from specified device register\n"); 51 fprintf(stdout, "set bus device reg value Set specified device register to value\n"); 52 } 53 54 void 55 print_command_error() 56 { 57 fprintf(stdout, "Invalid command, options are:\n"); 58 print_help(); 59 } 60 61 void 62 print_bus(mraa_board_t* board) 63 { 64 int i, bus; 65 for (i = 0; i < board->i2c_bus_count; ++i) { 66 char* busType; 67 switch (board->platform_type) { 68 case MRAA_INTEL_GALILEO_GEN1: 69 case MRAA_INTEL_GALILEO_GEN2: 70 case MRAA_INTEL_EDISON_FAB_C: 71 case MRAA_INTEL_DE3815: 72 case MRAA_INTEL_MINNOWBOARD_MAX: 73 case MRAA_RASPBERRY_PI: 74 case MRAA_BEAGLEBONE: 75 case MRAA_BANANA: 76 bus = i; 77 busType = "linux"; 78 break; 79 case MRAA_FTDI_FT4222: 80 busType = "ft4222"; 81 bus = mraa_get_sub_platform_id(i); 82 break; 83 default: 84 busType = "unknown"; 85 break; 86 } 87 int id = board->i2c_bus[i].bus_id; 88 fprintf(stdout, "Bus %3d: id=%02d type=%s ", bus, id, busType); 89 if (i == board->def_i2c_bus) 90 fprintf(stdout, " default"); 91 if (id == -1) 92 fprintf(stdout, " disabled"); 93 94 fprintf(stdout, "\n"); 95 } 96 } 97 98 void 99 print_busses() 100 { 101 print_bus(plat); 102 if (mraa_has_sub_platform()) 103 print_bus(plat->sub_platform); 104 } 105 106 mraa_result_t 107 i2c_get(int bus, uint8_t device_address, uint8_t register_address, uint8_t* data) 108 { 109 mraa_result_t status = MRAA_SUCCESS; 110 mraa_i2c_context i2c = mraa_i2c_init(bus); 111 if (i2c == NULL) { 112 return MRAA_ERROR_NO_RESOURCES; 113 } 114 status = mraa_i2c_address(i2c, device_address); 115 if (status != MRAA_SUCCESS) { 116 goto i2c_get_exit; 117 } 118 status = mraa_i2c_write_byte(i2c, register_address); 119 if (status != MRAA_SUCCESS) { 120 goto i2c_get_exit; 121 } 122 status = mraa_i2c_read(i2c, data, 1) == 1 ? MRAA_SUCCESS : MRAA_ERROR_UNSPECIFIED; 123 if (status != MRAA_SUCCESS) { 124 goto i2c_get_exit; 125 } 126 i2c_get_exit: 127 mraa_i2c_stop(i2c); 128 return status; 129 } 130 131 mraa_result_t 132 i2c_set(int bus, uint8_t device_address, uint8_t register_address, uint8_t data) 133 { 134 mraa_result_t status = MRAA_SUCCESS; 135 mraa_i2c_context i2c = mraa_i2c_init(bus); 136 if (i2c == NULL) { 137 return MRAA_ERROR_NO_RESOURCES; 138 } 139 status = mraa_i2c_address(i2c, device_address); 140 if (status != MRAA_SUCCESS) { 141 fprintf(stderr, "Could not set i2c device address\n"); 142 goto i2c_set_exit; 143 } 144 status = mraa_i2c_write_byte_data(i2c, data, register_address); 145 if (status != MRAA_SUCCESS) { 146 fprintf(stderr, "Could not write to i2c register. Status = %d\n", status); 147 goto i2c_set_exit; 148 } 149 i2c_set_exit: 150 mraa_i2c_stop(i2c); 151 return status; 152 } 153 154 void 155 i2c_detect_devices(int bus) 156 { 157 mraa_result_t status = MRAA_SUCCESS; 158 mraa_i2c_context i2c = mraa_i2c_init(bus); 159 if (i2c == NULL) { 160 return; 161 } 162 int addr; 163 for (addr = 0x0; addr < 0x80; ++addr) { 164 uint8_t value; 165 if ((addr) % 16 == 0) 166 printf("%02x: ", addr); 167 if (i2c_get(bus, addr, 0, &value) == MRAA_SUCCESS) 168 printf("%02x ", addr); 169 else 170 printf("-- "); 171 if ((addr + 1) % 16 == 0) 172 printf("\n"); 173 } 174 } 175 176 int 177 process_command(int argc, char** argv) 178 { 179 if (strcmp(argv[1], "help") == 0) { 180 print_help(); 181 return 0; 182 } else if (strcmp(argv[1], "version") == 0) { 183 print_version(); 184 return 0; 185 } else if (strcmp(argv[1], "list") == 0) { 186 print_busses(); 187 return 0; 188 } else if (strcmp(argv[1], "detect") == 0) { 189 if (argc == 3) { 190 int bus = strtol(argv[2], NULL, 0); 191 i2c_detect_devices(bus); 192 return 0; 193 } else { 194 print_command_error(); 195 return 1; 196 } 197 } else if ((strcmp(argv[1], "get") == 0)) { 198 if (argc == 5) { 199 int bus = strtol(argv[2], NULL, 0); 200 uint8_t device_address = strtol(argv[3], NULL, 0); 201 uint8_t register_address = strtol(argv[4], NULL, 0); 202 // fprintf(stdout, "Device %02X, Register = %02X\n", device_address, register_address); 203 uint8_t data; 204 if (i2c_get(bus, device_address, register_address, &data) == MRAA_SUCCESS) { 205 fprintf(stdout, "Register %#02X = %#02X\n", register_address, data); 206 return 0; 207 } else { 208 fprintf(stdout, "i2c get failed\n"); 209 return 1; 210 } 211 } else { 212 print_command_error(); 213 return 1; 214 } 215 } else if ((strcmp(argv[1], "set") == 0)) { 216 if (argc == 6) { 217 int bus = strtol(argv[2], NULL, 0); 218 uint8_t device_address = strtol(argv[3], NULL, 0); 219 uint8_t register_address = strtol(argv[4], NULL, 0); 220 uint8_t value = strtol(argv[5], NULL, 0); 221 fprintf(stdout, "Device %02X, Register = %02X, Value = %02X\n", device_address, 222 register_address, value); 223 if (i2c_set(bus, device_address, register_address, value) != MRAA_SUCCESS) { 224 fprintf(stdout, "i2c set failed\n"); 225 return 0; 226 } 227 return 1; 228 } else { 229 print_command_error(); 230 return 1; 231 } 232 } else { 233 print_command_error(); 234 return 1; 235 } 236 } 237 238 void 239 run_interactive_mode() 240 { 241 char command[80]; 242 while (1) { 243 int i, argc = 1; 244 char* argv[32]; 245 char* arg; 246 argv[0] = "mraa-i2c"; 247 fprintf(stdout, "Command: "); 248 fgets(command, 80, stdin); 249 command[strlen(command) - 1] = 0; 250 if (strcmp(command, "q") == 0) 251 return; 252 char* str = strtok(command, " "); 253 while (str != NULL) { 254 arg = malloc(strlen(str) + 1); 255 argv[argc++] = strcpy(arg, str); 256 str = strtok(NULL, " "); 257 } 258 process_command(argc, argv); 259 for (i = 1; i < argc; ++i) 260 free(argv[i]); 261 } 262 } 263 264 int 265 main(int argc, char** argv) 266 { 267 mraa_set_log_level(7); 268 if (argc == 1) { 269 run_interactive_mode(); 270 return 0; 271 } else 272 return process_command(argc, argv); 273 } 274