KT24-1110_65E-HA-651B/cpu/br25/spi_test.c

207 lines
5.4 KiB
C
Raw Normal View History

2024-11-10 10:44:17 +00:00
#include "system/includes.h"
#include "media/includes.h"
#include "asm/spi.h"
#include "generic/log.h"
#if 0
/*
[[[ README ]]]
1. spi测试demo提供了spi.c的API使用例程spi的环回测试
spi1设置为主机模式spi2设置为从机模式spi1发送数据到spi2spi2
2. demo涉及BYTE收发测试及DMA收发测试SPI_TEST_MODE选择
demo还涉及到spi中断中调用可用于中断的spi API的使用
3. spi.c的API不包含CS引脚CS由API以外控制
4. board_xxx.c中定义配置结构体spi1spi1_p_data
5. spi的DMA地址需要4字节对齐
6. spi.c的API带有spi0spi flash的芯片上使用可能会出问题
使spi0
*/
#define SPI1_CS_OUT() \
do { \
JL_PORTB->DIR &= ~BIT(4); \
JL_PORTB->DIE |= BIT(4); \
JL_PORTB->PU &= ~BIT(4); \
JL_PORTB->PD &= ~BIT(4); \
} while(0)
#define SPI1_CS_L() (JL_PORTB->OUT &= ~BIT(4))
#define SPI1_CS_H() (JL_PORTB->OUT |= BIT(4))
#define SPI2_CS_IN() \
do { \
JL_PORTA->DIR |= BIT(3); \
JL_PORTA->DIE |= BIT(3); \
JL_PORTA->PU &= ~BIT(3); \
JL_PORTA->PD &= ~BIT(3); \
} while (0)
#define SPI2_READ_CS() (JL_PORTA->IN & BIT(3))
static u8 slave_dir = 1;
static u8 spi1_send_buf[100] __attribute__((aligned(4)));
static u8 spi1_recv_buf[100] __attribute__((aligned(4)));
static u8 spi2_send_buf[100] __attribute__((aligned(4)));
static u8 spi2_recv_buf[100] __attribute__((aligned(4)));
static spi_dev spi1_hdl = 1;
static spi_dev spi2_hdl = 2;
#define SPI_TEST_BYTE_MODE 0x01
#define SPI_TEST_DMA_MODE 0x02
//测试模式选择
#define SPI_TEST_MODE SPI_TEST_BYTE_MODE
static void my_put_u8hex(u8 b)
{
u8 dat;
dat = b / 16;
if (dat >= 0 && dat <= 9) {
putchar('0' + dat);
} else {
putchar('A' + dat - 10);
}
dat = b % 16;
if (dat >= 0 && dat <= 9) {
putchar('0' + dat);
} else {
putchar('A' + dat - 10);
}
putchar(' ');
}
//中断函数,需以下特殊声明
__attribute__((interrupt("")))
static void spi2_isr()
{
static int i = 0;
if (spi_get_pending(spi2_hdl)) {
spi_clear_pending(spi2_hdl);
if (SPI2_READ_CS()) {
return;
}
#if SPI_TEST_MODE == SPI_TEST_BYTE_MODE
if (slave_dir == 1) {
spi2_recv_buf[i] = spi_recv_byte_for_isr(spi2_hdl);
spi_send_byte_for_isr(spi2_hdl, spi2_recv_buf[i]);
i >= 100 ? i = 0 : i++;
slave_dir = 0;
} else {
slave_dir = 1;
}
#elif SPI_TEST_MODE == SPI_TEST_DMA_MODE
if (slave_dir == 1) {
spi_dma_set_addr_for_isr(spi2_hdl, spi2_recv_buf, 100, 0);
slave_dir = 0;
} else {
slave_dir = 1;
}
#endif
}
}
#if 1 //仅用于spi demo正式工程请放到board_xxx.c文件中
/* const struct spi_platform_data spi0_p_data = { */
/* .port = 'A', */
/* .mode = SPI_MODE_BIDIR_1BIT, */
/* .clk = 1000000, */
/* .role = SPI_ROLE_MASTER, */
/* }; */
const struct spi_platform_data spi1_p_data = {
.port = 'A',
.mode = SPI_MODE_BIDIR_1BIT,
.clk = 1000000,
.role = SPI_ROLE_MASTER,
};
const struct spi_platform_data spi2_p_data = {
.port = 'A',
.mode = SPI_MODE_BIDIR_1BIT,
.clk = 1000000,
.role = SPI_ROLE_SLAVE,
};
#endif
void spi_test_main()
{
int i;
int err;
spi_open(spi1_hdl);
spi_open(spi2_hdl);
spi_set_ie(spi2_hdl, 1);
//配置中断优先级,中断函数
request_irq(IRQ_SPI2_IDX, 3, spi2_isr, 0);
SPI1_CS_OUT();
SPI2_CS_IN();
SPI1_CS_H();
for (i = 0; i < 100; i++) {
spi1_send_buf[i] = i % 26 + 'A';
spi1_recv_buf[i] = 0;
}
puts(">>> spi test start\n");
#if SPI_TEST_MODE == SPI_TEST_BYTE_MODE
SPI1_CS_L();
for (i = 0; i < 100; i++) {
err = spi_send_byte(spi1_hdl, spi1_send_buf[i]);
if (err) {
puts("spi1 byte send timeout\n");
break;
}
delay(100);
spi1_recv_buf[i] = spi_recv_byte(spi1_hdl, &err);
if (err) {
puts("spi1 byte recv timeout\n");
break;
}
delay(100);
}
SPI1_CS_H();
#elif SPI_TEST_MODE == SPI_TEST_DMA_MODE
spi_dma_set_addr_for_isr(spi2_hdl, spi2_recv_buf, 100, 1);
SPI1_CS_L();
err = spi_dma_send(spi1_hdl, spi1_send_buf, 100);
if (err < 0) {
puts("spi1 dma send timeout\n");
goto __out_dma;
}
//delay(100);
err = spi_dma_recv(spi1_hdl, spi1_recv_buf, 100);
if (err < 0) {
puts("spi1 dma recv timeout\n");
goto __out_dma;
}
//delay(100);
__out_dma:
SPI1_CS_H();
#endif
puts("<<< spi test end\n");
puts("\nspi master receivce buffer:\n");
for (i = 0; i < 100; i++) {
//my_put_u8hex(spi1_recv_buf[i]);
putchar(spi1_recv_buf[i]), putchar(0x20);
if (i % 16 == 15) {
putchar('\n');
}
}
if (i % 16) {
putchar('\n');
}
if (!memcmp(spi1_send_buf, spi1_recv_buf, 100)) {
puts("\nspi test pass\n");
} else {
puts("\nspi test fail\n");
}
spi_close(spi1_hdl);
spi_close(spi2_hdl);
}
#endif