From 1e563e2b731d928942f43e1341c8c50b0faf1c01 Mon Sep 17 00:00:00 2001
From: guowenxue <guowenxue@gmail.com>
Date: Fri, 31 May 2024 11:39:31 +0800
Subject: [PATCH]  APPS:IGKBoard-IMX6ULL: Add test-apps source code:

---
 drivers/test-apps/spi_test.c |  205 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 205 insertions(+), 0 deletions(-)

diff --git a/drivers/test-apps/spi_test.c b/drivers/test-apps/spi_test.c
new file mode 100644
index 0000000..8d80e8a
--- /dev/null
+++ b/drivers/test-apps/spi_test.c
@@ -0,0 +1,205 @@
+/*********************************************************************************
+ *      Copyright:  (C) 2024 LingYun IoT System Studio
+ *                  All rights reserved.
+ *
+ *       Filename:  spi_test.c
+ *    Description:  This file is SPI loop test program
+ *
+ *        Version:  1.0.0(05/23/2024)
+ *         Author:  Guo Wenxue <guowenxue@gmail.com>
+ *      ChangeLog:  1, Release initial version on "05/23/2024 07:51:06 PM"
+ *
+ ********************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/spi/spidev.h>
+
+typedef struct spi_ctx_s
+{
+    int         fd;
+    char        dev[64];
+    uint8_t     bits;
+    uint16_t    delay;
+    uint32_t    mode;
+    uint32_t    speed;
+} spi_ctx_t;
+
+static int spi_init(spi_ctx_t *spi_ctx);
+static int transfer(spi_ctx_t *spi_ctx, uint8_t const *tx, uint8_t const *rx, size_t len);
+
+static void program_usage(char *progname)
+{
+    printf("Usage: %s [OPTION]...\n", progname);
+    printf(" %s is a program to test IGKBoard loop spi\n", progname);
+
+    printf("\nMandatory arguments to long options are mandatory for short options too:\n");
+    printf(" -d[device  ]  Specify SPI device, such as: /dev/spidev0.0\n");
+    printf(" -s[speed   ]  max speed (Hz), such as: -s 500000\n");
+    printf(" -p[print   ]  Send data (such as: -p 1234/xde/xad)\n");
+
+    printf("\n%s version 1.0\n", progname);
+    return;
+}
+
+int main(int argc,char * argv[])
+{
+    spi_ctx_t          spi_ctx;
+    uint32_t           spi_speed = 500000;  // Default SPI speed 500KHz
+    char              *spi_dev = "/dev/spidev0.0"; // Default SPI device
+    char              *input_tx = "Hello LingYun"; // Default transfer data
+    uint8_t            rx_buffer[128];
+    int                opt;
+    char               *progname=NULL;
+
+    struct option long_options[] = {
+        {"device", required_argument, NULL, 'd'},
+        {"speed", required_argument, NULL, 's'},
+        {"print", required_argument, NULL, 'p'},
+        {"help", no_argument, NULL, 'h'},
+        {NULL, 0, NULL, 0}
+    };
+
+    progname = (char *)basename(argv[0]);
+
+    while((opt = getopt_long(argc, argv, "d:s:p:h", long_options, NULL)) != -1)
+    {
+        switch (opt)
+        {
+        case 'd':
+            spi_dev = optarg;
+            break;
+
+        case 's':
+            spi_speed = atoi(optarg);
+            break;
+
+        case 'p':
+            input_tx = optarg;
+            break;
+
+        case 'h':
+            program_usage(progname);
+            return 0;
+
+        default:
+            break;
+        }
+    }
+
+    memset(&spi_ctx, 0, sizeof(spi_ctx));
+    strncpy(spi_ctx.dev, spi_dev, sizeof(spi_ctx.dev));
+    spi_ctx.bits = 8;
+    spi_ctx.delay = 100;
+    spi_ctx.mode = SPI_MODE_2;
+    spi_ctx.speed = spi_speed;
+
+    if( spi_init(&spi_ctx) < 0 )
+    {
+        printf("Initial SPI device '%s' failed.\n", spi_ctx.dev);
+        return -1;
+    }
+    printf("Initial SPI device '%s' okay.\n", spi_ctx.dev);
+
+    if ( transfer(&spi_ctx, input_tx, rx_buffer, strlen(input_tx)) < 0 )
+    {
+        printf("spi transfer error\n");
+        return -2;
+    }
+
+    printf("tx_buffer: | %s |\n", input_tx);
+    printf("rx_buffer: | %s |\n", rx_buffer);
+
+    return 0;
+}
+
+int transfer(spi_ctx_t *spi_ctx, uint8_t const *tx, uint8_t const *rx, size_t len)
+{
+    struct spi_ioc_transfer tr = {
+        .tx_buf = (unsigned long )tx,
+        .rx_buf = (unsigned long )rx,
+        .len = len,
+        .delay_usecs = spi_ctx->delay,
+        .speed_hz = spi_ctx->speed,
+        .bits_per_word = spi_ctx->bits,
+    };
+
+    if( ioctl(spi_ctx->fd, SPI_IOC_MESSAGE(1), &tr) < 0)
+    {
+        printf("ERROR: SPI transfer failure: %s\n ", strerror(errno));
+        return -1;
+    }
+
+    return 0;
+}
+
+int spi_init(spi_ctx_t *spi_ctx)
+{
+    int ret;
+    spi_ctx->fd = open(spi_ctx->dev, O_RDWR);
+    if(spi_ctx->fd < 0)
+    {
+        printf("open %s error\n", spi_ctx->dev);
+        return -1;
+    }
+
+    ret = ioctl(spi_ctx->fd, SPI_IOC_RD_MODE, &spi_ctx->mode);
+    if( ret < 0 )
+    {
+        printf("ERROR: SPI set SPI_IOC_RD_MODE [0x%x] failure: %s\n ", spi_ctx->mode, strerror(errno));
+        goto cleanup;
+    }
+
+    ret = ioctl(spi_ctx->fd, SPI_IOC_WR_MODE, &spi_ctx->mode);
+    if( ret < 0 )
+    {
+        printf("ERROR: SPI set SPI_IOC_WR_MODE [0x%x] failure: %s\n ", spi_ctx->mode, strerror(errno));
+        goto cleanup;
+    }
+
+    ret = ioctl(spi_ctx->fd, SPI_IOC_RD_BITS_PER_WORD, &spi_ctx->bits);
+    if( ret < 0 )
+    {
+        printf("ERROR: SPI set SPI_IOC_RD_BITS_PER_WORD [%d] failure: %s\n ", spi_ctx->bits, strerror(errno));
+        goto cleanup;
+    }
+    ret = ioctl(spi_ctx->fd, SPI_IOC_WR_BITS_PER_WORD, &spi_ctx->bits);
+    if( ret < 0 )
+    {
+        printf("ERROR: SPI set SPI_IOC_WR_BITS_PER_WORD [%d] failure: %s\n ", spi_ctx->bits, strerror(errno));
+        goto cleanup;
+    }
+
+    ret = ioctl(spi_ctx->fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_ctx->speed);
+    if( ret == -1)
+    {
+        printf("ERROR: SPI set SPI_IOC_WR_MAX_SPEED_HZ [%d] failure: %s\n ", spi_ctx->speed, strerror(errno));
+        goto cleanup;
+    }
+    ret = ioctl(spi_ctx->fd, SPI_IOC_RD_MAX_SPEED_HZ, &spi_ctx->speed);
+    if( ret == -1)
+    {
+        printf("ERROR: SPI set SPI_IOC_RD_MAX_SPEED_HZ [%d] failure: %s\n ", spi_ctx->speed, strerror(errno));
+        goto cleanup;
+    }
+
+    printf("spi mode: 0x%x\n", spi_ctx->mode);
+    printf("bits per word: %d\n", spi_ctx->bits);
+    printf("max speed: %d Hz (%d KHz)\n", spi_ctx->speed, spi_ctx->speed / 1000);
+
+   return spi_ctx->fd;
+
+cleanup:
+   close(spi_ctx->fd);
+   return -1;
+}

--
Gitblit v1.9.1