Changeset 5911

Show
Ignore:
Timestamp:
01/29/11 18:15:01 (2 years ago)
Author:
groeck
Message:

Added support to write SMBus and I2C block commands to i2cset

Location:
i2c-tools/trunk
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • i2c-tools/trunk/CHANGES

    r5894 r5911  
    44SVN 
    55  i2c-dev.h: Make value arrays const for block write functions 
     6  i2cset: Add support for SMBus and I2C block writes 
    67 
    783.0.3 (2010-12-12) 
  • i2c-tools/trunk/tools/i2cset.8

    r5771 r5911  
    1313.I data-address 
    1414.RI [ value ] 
     15.RI ... 
    1516.RI [ mode ] 
    1617.br 
     
    6364.PP 
    6465The \fIvalue\fR parameter, if specified, is the value to write to that 
    65 location on the chip. If this parameter is omited, then a short write is 
     66location on the chip. If this parameter is omitted, then a short write is 
    6667issued. For most chips, it simply sets an internal pointer to the target 
    6768location, but doesn't actually write to that location. For a few chips 
    6869though, in particular simple ones with a single register, this short write 
    69 is an actual write. 
     70is an actual write. If the mode parameter is \fBs\fP or \fBi\fP, multiple 
     71values can be specified. 
    7072.PP 
    71 The \fImode\fR parameter, if specified, is one of the letters \fBb\fP or 
    72 \fBw\fP, corresponding to a write size of a single byte or a 16-bit word, 
    73 respectively. A \fBp\fP can also be appended to the \fImode\fR parameter to 
    74 enable PEC. If the \fImode\fR parameter is omitted, i2cset defaults to byte 
     73The \fImode\fR parameter, if specified, is one of the letters \fBb\fP, 
     74\fBw\fP, \fBs\fP, or \fBi\fP, corresponding to a write size of a single byte, 
     75a 16-bit word, a SMBus block write, or an I2C block write, respectively. 
     76For SMBus and I2C block writes, the write size is determined by the number 
     77of \fIvalue\fR parameters. 
     78Except for I2C block writes, a \fBp\fP can also be appended to the \fImode\fR 
     79parameter to enable PEC. 
     80If the \fImode\fR parameter is omitted, i2cset defaults to byte 
    7581mode without PEC. The \fIvalue\fR provided must be within range for the 
    76 specified data type (0x00-0xFF for bytes, 0x0000-0xFFFF for words). 
     82specified data type (0x00-0xFF for byte and block writes, 0x0000-0xFFFF 
     83for words). 
    7784Another possible mode is \fBc\fP, which doesn't write any value (so-called 
    7885short write). You usually don't have to specify this mode, as it is the 
  • i2c-tools/trunk/tools/i2cset.c

    r5885 r5911  
    3636{ 
    3737        fprintf(stderr, 
    38                 "Usage: i2cset [-f] [-y] [-m MASK] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] [MODE]\n" 
     38                "Usage: i2cset [-f] [-y] [-m MASK] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]\n" 
    3939                "  I2CBUS is an integer or an I2C bus name\n" 
    4040                "  ADDRESS is an integer (0x03 - 0x77)\n" 
     
    4343                "    b (byte data, default)\n" 
    4444                "    w (word data)\n" 
     45                "    i (I2C block data)\n" 
     46                "    s (SMBus block data)\n" 
    4547                "    Append p for SMBus PEC\n"); 
    4648        exit(1); 
     
    7981                } 
    8082                break; 
     83 
     84        case I2C_SMBUS_BLOCK_DATA: 
     85                if (!(funcs & I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)) { 
     86                        fprintf(stderr, MISSING_FUNC_FMT, "SMBus block write"); 
     87                        return -1; 
     88                } 
     89                break; 
     90        case I2C_SMBUS_I2C_BLOCK_DATA: 
     91                if (!(funcs & I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { 
     92                        fprintf(stderr, MISSING_FUNC_FMT, "I2C block write"); 
     93                        return -1; 
     94                } 
     95                break; 
    8196        } 
    8297 
     
    91106 
    92107static int confirm(const char *filename, int address, int size, int daddress, 
    93                    int value, int vmask, int pec) 
     108                   int value, int vmask, const unsigned char *block, int len, 
     109                   int pec) 
    94110{ 
    95111        int dont = 0; 
     
    110126        if (size == I2C_SMBUS_BYTE) 
    111127                fprintf(stderr, "no data.\n"); 
    112         else 
     128        else if (size == I2C_SMBUS_BLOCK_DATA || 
     129                 size == I2C_SMBUS_I2C_BLOCK_DATA) { 
     130                int i; 
     131 
     132                fprintf(stderr, "data"); 
     133                for (i = 0; i < len; i++) 
     134                        fprintf(stderr, " 0x%02x", block[i]); 
     135                fprintf(stderr, ", mode %s.\n", size == I2C_SMBUS_BLOCK_DATA 
     136                        ? "smbus block" : "i2c block"); 
     137        } else 
    113138                fprintf(stderr, "data 0x%02x%s, mode %s.\n", value, 
    114139                        vmask ? " (masked)" : "", 
     
    137162        int flags = 0; 
    138163        int force = 0, yes = 0, version = 0, readback = 0; 
     164        unsigned char block[I2C_SMBUS_BLOCK_MAX]; 
     165        int len; 
    139166 
    140167        /* handle (optional) flags first */ 
     
    181208        } 
    182209 
     210        /* check for block data */ 
     211        len = 0; 
     212        if (argc > flags + 5) { 
     213                switch (argv[argc-1][0]) { 
     214                case 's': size = I2C_SMBUS_BLOCK_DATA; break; 
     215                case 'i': size = I2C_SMBUS_I2C_BLOCK_DATA; break; 
     216                default: 
     217                        size = 0; 
     218                        break; 
     219                } 
     220                if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) { 
     221                        pec = argv[argc-1][1] == 'p'; 
     222                        if (pec && size == I2C_SMBUS_I2C_BLOCK_DATA) { 
     223                                fprintf(stderr, "Error: PEC not supported for I2C block writes!\n"); 
     224                                help(); 
     225                        } 
     226                        for (len = 0; len < (int)sizeof(block) && len + flags + 5 < argc; len++) { 
     227                                value = strtol(argv[flags + len + 4], &end, 0); 
     228                                if (*end || value < 0 || value > 0xff) { 
     229                                        fprintf(stderr, "Error: Block data value invalid!\n"); 
     230                                        help(); 
     231                                } 
     232                                block[len] = value; 
     233                        } 
     234                        goto dofile; 
     235                } 
     236        } 
     237 
    183238        if (argc > flags + 4) { 
    184239                if (!strcmp(argv[flags+4], "c") 
     
    237292        } 
    238293 
     294dofile: 
    239295        file = open_i2c_dev(i2cbus, filename, sizeof(filename), 0); 
    240296        if (file < 0 
     
    244300 
    245301        if (!yes && !confirm(filename, address, size, daddress, 
    246                              value, vmask, pec)) 
     302                             value, vmask, block, len, pec)) 
    247303                exit(0); 
    248304 
     
    300356                res = i2c_smbus_write_word_data(file, daddress, value); 
    301357                break; 
     358        case I2C_SMBUS_BLOCK_DATA: 
     359                res = i2c_smbus_write_block_data(file, daddress, len, block); 
     360                break; 
     361        case I2C_SMBUS_I2C_BLOCK_DATA: 
     362                res = i2c_smbus_write_i2c_block_data(file, daddress, len, block); 
     363                break; 
    302364        default: /* I2C_SMBUS_BYTE_DATA */ 
    303365                res = i2c_smbus_write_byte_data(file, daddress, value); 
     366                break; 
    304367        } 
    305368        if (res < 0) {