Files
SOMEIP/source/spi_dev/spi4test.c

140 lines
4.0 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* spi_slave_recv_loop.c - SPI从设备持续接收程序
*
* 功能SoC作为SPI从设备配置与MCU主设备对齐循环接收并打印数据
* MCU每秒发送一帧8字节
*
* MCU主设备配置需对齐
* Mode : SPI_MODE_0 (CPOL=0, CPHA=0)
* Bits/Word : 8
* Speed : 1 MHz
* 发送数据 : {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
*
* 编译aarch64-linux-gnu-gcc -o spi_slave_recv_loop spi_slave_recv_loop.c
* 运行:./spi_slave_recv_loop
* 退出:按 Ctrl+C
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
/* ========== SPI配置必须与MCU主设备完全一致========== */
#define SPI_DEVICE "/dev/spidev4.0"
#define SPI_MODE SPI_MODE_0 /* CPOL=1, CPHA=1 */
#define SPI_BITS 8
#define SPI_SPEED 1000000 /* 1MHz */
#define FRAME_LEN 128 /* 每帧64字节 */
/* ===================================================== */
static volatile int keep_running = 1;
void sigint_handler(int sig) {
(void)sig;
keep_running = 0;
printf("\n[INFO] User interrupted, exiting...\n");
}
int main(void)
{
uint8_t buf[FRAME_LEN];
int fd, ret;
unsigned int frame_count = 0;
/* 注册退出信号 */
signal(SIGINT, sigint_handler);
/* 1. 打开 SPI 设备 */
fd = open(SPI_DEVICE, O_RDWR);
if (fd < 0) {
perror("open " SPI_DEVICE);
return 1;
}
/* 2. 配置 SPI 模式 */
uint8_t mode = SPI_MODE;
mode |= SPI_LSB_FIRST;
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1) {
perror("SPI_IOC_WR_MODE");
close(fd);
return 1;
}
/* 3. 配置每字位数 */
uint8_t bits = SPI_BITS;
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1) {
perror("SPI_IOC_WR_BITS_PER_WORD");
close(fd);
return 1;
}
/* 4. 配置最大时钟频率 */
uint32_t speed = SPI_SPEED;
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1) {
perror("SPI_IOC_WR_MAX_SPEED_HZ");
close(fd);
return 1;
}
/* 5. 回读验证配置 */
ioctl(fd, SPI_IOC_RD_MODE, &mode);
ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
printf("========================================\n");
printf("SPI Slave Config (aligned with MCU)\n");
printf("========================================\n");
printf("Device : %s\n", SPI_DEVICE);
printf("Mode : %d (CPOL=%d, CPHA=%d)\n",
mode, (mode & SPI_CPOL) ? 1 : 0, (mode & SPI_CPHA) ? 1 : 0);
printf("Bits/Word : %d\n", bits);
printf("Max Speed : %d Hz\n", speed);
printf("Frame length: %d bytes\n", FRAME_LEN);
printf("========================================\n");
printf("Waiting for MCU (master) to send data...\n");
printf("Press Ctrl+C to stop.\n\n");
/* 6. 循环接收数据 */
while (keep_running) {
memset(buf, 0, FRAME_LEN);
ret = read(fd, buf, FRAME_LEN);
if (ret < 0) {
perror("read");
break;
} else if (ret == 0) {
/* 非阻塞模式可能返回0但这里用了阻塞模式一般不会出现 */
//continue;
}
frame_count++;
printf("\n========== Frame #%u (%d bytes) ==========\n", frame_count, ret);
printf("HEX : ");
for (int i = 0; i < ret; i++)
printf("0x%02X ", buf[i]);
printf("\n");
printf("ASCII: ");
for (int i = 0; i < ret; i++)
printf(" %c ", (buf[i] >= 0x20 && buf[i] < 0x7F) ? buf[i] : '.');
printf("\n");
printf("DEC : ");
for (int i = 0; i < ret; i++)
printf("%3d ", buf[i]);
printf("\n");
printf("=========================================\n");
}
close(fd);
return 0;
}