uboot/common/cmd_spi.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002
   3 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24/*
  25 * SPI Read/Write Utilities
  26 */
  27
  28#include <common.h>
  29#include <command.h>
  30#include <spi.h>
  31
  32/*-----------------------------------------------------------------------
  33 * Definitions
  34 */
  35
  36#ifndef MAX_SPI_BYTES
  37#   define MAX_SPI_BYTES 32     /* Maximum number of bytes we can handle */
  38#endif
  39
  40#ifndef CONFIG_DEFAULT_SPI_BUS
  41#   define CONFIG_DEFAULT_SPI_BUS       0
  42#endif
  43#ifndef CONFIG_DEFAULT_SPI_MODE
  44#   define CONFIG_DEFAULT_SPI_MODE      SPI_MODE_0
  45#endif
  46
  47/*
  48 * Values from last command.
  49 */
  50static unsigned int     bus;
  51static unsigned int     cs;
  52static unsigned int     mode;
  53static int              bitlen;
  54static uchar            dout[MAX_SPI_BYTES];
  55static uchar            din[MAX_SPI_BYTES];
  56
  57/*
  58 * SPI read/write
  59 *
  60 * Syntax:
  61 *   spi {dev} {num_bits} {dout}
  62 *     {dev} is the device number for controlling chip select (see TBD)
  63 *     {num_bits} is the number of bits to send & receive (base 10)
  64 *     {dout} is a hexadecimal string of data to send
  65 * The command prints out the hexadecimal string received via SPI.
  66 */
  67
  68int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  69{
  70        struct spi_slave *slave;
  71        char  *cp = 0;
  72        uchar tmp;
  73        int   j;
  74        int   rcode = 0;
  75
  76        /*
  77         * We use the last specified parameters, unless new ones are
  78         * entered.
  79         */
  80
  81        if ((flag & CMD_FLAG_REPEAT) == 0)
  82        {
  83                if (argc >= 2) {
  84                        mode = CONFIG_DEFAULT_SPI_MODE;
  85                        bus = simple_strtoul(argv[1], &cp, 10);
  86                        if (*cp == ':') {
  87                                cs = simple_strtoul(cp+1, &cp, 10);
  88                        } else {
  89                                cs = bus;
  90                                bus = CONFIG_DEFAULT_SPI_BUS;
  91                        }
  92                        if (*cp == '.')
  93                                mode = simple_strtoul(cp+1, NULL, 10);
  94                }
  95                if (argc >= 3)
  96                        bitlen = simple_strtoul(argv[2], NULL, 10);
  97                if (argc >= 4) {
  98                        cp = argv[3];
  99                        for(j = 0; *cp; j++, cp++) {
 100                                tmp = *cp - '0';
 101                                if(tmp > 9)
 102                                        tmp -= ('A' - '0') - 10;
 103                                if(tmp > 15)
 104                                        tmp -= ('a' - 'A');
 105                                if(tmp > 15) {
 106                                        printf("Hex conversion error on %c\n", *cp);
 107                                        return 1;
 108                                }
 109                                if((j % 2) == 0)
 110                                        dout[j / 2] = (tmp << 4);
 111                                else
 112                                        dout[j / 2] |= tmp;
 113                        }
 114                }
 115        }
 116
 117        if ((bitlen < 0) || (bitlen >  (MAX_SPI_BYTES * 8))) {
 118                printf("Invalid bitlen %d\n", bitlen);
 119                return 1;
 120        }
 121
 122        slave = spi_setup_slave(bus, cs, 1000000, mode);
 123        if (!slave) {
 124                printf("Invalid device %d:%d\n", bus, cs);
 125                return 1;
 126        }
 127
 128        spi_claim_bus(slave);
 129        if(spi_xfer(slave, bitlen, dout, din,
 130                                SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
 131                printf("Error during SPI transaction\n");
 132                rcode = 1;
 133        } else {
 134                for(j = 0; j < ((bitlen + 7) / 8); j++) {
 135                        printf("%02X", din[j]);
 136                }
 137                printf("\n");
 138        }
 139        spi_release_bus(slave);
 140        spi_free_slave(slave);
 141
 142        return rcode;
 143}
 144
 145/***************************************************/
 146
 147U_BOOT_CMD(
 148        sspi,   5,      1,      do_spi,
 149        "SPI utility command",
 150        "[<bus>:]<cs>[.<mode>] <bit_len> <dout> - Send and receive bits\n"
 151        "<bus>     - Identifies the SPI bus\n"
 152        "<cs>      - Identifies the chip select\n"
 153        "<mode>    - Identifies the SPI mode to use\n"
 154        "<bit_len> - Number of bits to send (base 10)\n"
 155        "<dout>    - Hexadecimal string that gets sent"
 156);
 157