Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:19

0001 /*
0002  * SPDX-License-Identifier: BSD-2-Clause
0003  *
0004  * Copyright (C) 2020 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #include <dev/spi/spi.h>
0029 #include <fcntl.h>
0030 #include <stdio.h>
0031 #include <stdlib.h>
0032 
0033 #include <rtems/shell.h>
0034 
0035 static const char rtems_spi_shell_usage [] =
0036   "simple SPI read / write\n"
0037   "\n"
0038   "spi [-loh] [-c <cs>] [-s <speed>] [-m <mode>] <SPI_BUS> xx [xx [..]]\n"
0039   "    <SPI_BUS>  Bus device to use\n"
0040   "    xx         Hex value of a byte to send\n"
0041   "    -c <cs>    Use chip select <cs> (default: None)\n"
0042   "    -m <mode>  Use SPI mode <mode> (default: 0)\n"
0043   "    -l         Send LSB first\n"
0044   "    -o         Use loopback mode\n"
0045   "    -s <speed> Bus speed in hz\n"
0046   "    -h         Print this help\n";
0047 
0048 static int rtems_spi_shell_main(int argc, char *argv[])
0049 {
0050   uint8_t buffer[argc - 1];
0051   size_t len = 0;
0052   int i;
0053   size_t j;
0054   int rv;
0055   int fd;
0056   char *bus = NULL;
0057   unsigned long mode;
0058   spi_ioc_transfer msg = {
0059     .len = 0,
0060     .rx_buf = buffer,
0061     .tx_buf = buffer,
0062     .speed_hz = 100000,
0063     .bits_per_word = 8,
0064     .cs_change = true,
0065     .mode = SPI_MODE_0 | SPI_NO_CS,
0066   };
0067 
0068   for (i = 1; i < argc; ++i) {
0069     if (argv[i][0] == '-') {
0070       switch (argv[i][1]) {
0071       case ('c'):
0072         errno = 0;
0073         msg.mode &= ~SPI_NO_CS;
0074         msg.cs = (uint8_t) strtoul(argv[i+1], NULL, 0);
0075         ++i;
0076         if (errno != 0) {
0077           printf("Couldn't process chip select\n");
0078           return 1;
0079         }
0080         break;
0081       case ('m'):
0082         errno = 0;
0083         mode = strtoul(argv[i+1], NULL, 0);
0084         ++i;
0085         if (errno != 0 || mode > 3) {
0086           printf("Couldn't process mode\n");
0087           return 1;
0088         }
0089         msg.mode &= ~(SPI_CPOL | SPI_CPHA);
0090         msg.mode |= mode;
0091         break;
0092       case ('s'):
0093         errno = 0;
0094         msg.speed_hz = (uint32_t) strtoul(argv[i+1], NULL, 0);
0095         ++i;
0096         if (errno != 0) {
0097           printf("Couldn't process speed\n");
0098           return 1;
0099         }
0100         break;
0101       case ('l'):
0102         msg.mode |= SPI_LSB_FIRST;
0103         break;
0104       case ('o'):
0105         msg.mode |= SPI_LOOP;
0106         break;
0107       case ('h'):
0108         /* fallthrough */
0109       default:
0110         printf(rtems_spi_shell_usage);
0111         return 1;
0112       }
0113     } else if (bus == NULL) {
0114       bus = argv[i];
0115     } else {
0116       errno = 0;
0117       buffer[len] = (uint8_t) strtol(argv[i], NULL, 16);
0118       if (errno != 0) {
0119         printf("Couldn't process '%s'\n", argv[i]);
0120         return 1;
0121       }
0122       ++len;
0123     }
0124   }
0125 
0126   if (len == 0) {
0127     printf("Nothing to do\n");
0128     return 0;
0129   }
0130 
0131   fd = open(bus, O_RDWR);
0132   if (fd < 0) {
0133     perror("Couldn't open bus");
0134     return 1;
0135   }
0136   msg.len = len;
0137   rv = ioctl(fd, SPI_IOC_MESSAGE(1), &msg);
0138   if (rv == -1) {
0139     perror("Couldn't send the message");
0140   } else {
0141     printf("received:");
0142     for (j = 0; j < len; ++j) {
0143       printf(" %02x", buffer[j]);
0144     }
0145     printf("\n");
0146   }
0147   close(fd);
0148 
0149   return 0;
0150 }
0151 
0152 rtems_shell_cmd_t rtems_shell_SPI_Command = {
0153   .name = "spi",
0154   .usage = rtems_spi_shell_usage,
0155   .topic = "misc",
0156   .command = rtems_spi_shell_main,
0157 };