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