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