SPI
Overview
以 AC638N 为例,配置两个spi的样机自发自收环回测试。spi1设置为主机模式,spi2设置为从机模式,spi1发送数据到spi2,然后spi1接收spi2原样返回的数据,然后比较发送出去的数据与接收的数据是否一致,一致则说明验证通过。提供 SPI 的应用示例、工程配置、API 介绍和常见问题。
应用示例
SPI 的具体源代码详见 sdk/bsp/AC638N/src/spi.c
spi.c
中参考示例如下: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);//配置中断优先级,中断函数 //spi cs init spi_cs_init(IO_PORTB_04, 0); //spi1 cs out spi_cs_init(IO_PORTA_03, 1); //spi2 cs in for (i = 0; i < 100; i++) { spi1_send_buf[i] = i % 26 + 'A'; spi1_recv_buf[i] = 0; } log_info(">>> spi test start"); #if SPI_TEST_BYTE_MODE_EN log_info(">>> spi byte test"); gpio_write(IO_PORTB_04, 0); for (i = 0; i < 100; i++) { err = spi_send_byte(spi1_hdl, spi1_send_buf[i]); if (err) { log_info("spi1 byte send timeout"); break; } delay(100); spi1_recv_buf[i] = spi_recv_byte(spi1_hdl, &err); if (err) { log_info("spi1 byte recv timeout"); break; } delay(100); } gpio_write(IO_PORTB_04, 1); #else log_info(">>> spi dma test"); spi_dma_set_addr_for_isr(spi2_hdl, spi2_recv_buf, 100, 1); gpio_write(IO_PORTB_04, 0); err = spi_dma_send(spi1_hdl, spi1_send_buf, 100); if (err < 0) { log_info("spi1 dma send timeout"); goto __out_dma; } err = spi_dma_recv(spi1_hdl, spi1_recv_buf, 100);//delay(100); if (err < 0) { log_info("spi1 dma recv timeout"); goto __out_dma; } __out_dma://delay(100); gpio_write(IO_PORTB_04, 1); #endif log_info("<<< spi test end"); log_info("\nspi master receivce buffer:\n"); put_buf(spi1_recv_buf, 100); if (!memcmp(spi1_send_buf, spi1_recv_buf, 100)) { log_info("\nspi test pass\n"); } else { log_info("\nspi test fail\n"); } spi_close(spi1_hdl); spi_close(spi2_hdl); }
工程配置
在 sdk/bsp/AC638N/board/board_demo.c 中配置SPI:
/*********** SPI config ***********/ #if TCFG_HW_SPI1_ENABLE const struct spi_platform_data spi1_p_data = { .port = { IO_PORTB_06, //CLK IO_PORTB_07, //DO IO_PORTB_08, //DI }, .mode = SPI_MODE_BIDIR_1BIT, .clk = 1000000, .role = SPI_ROLE_MASTER, }; #endif #if TCFG_HW_SPI2_ENABLE const struct spi_platform_data spi2_p_data = { .port = { IO_PORTB_01, //CLK IO_PORTB_02, //DO IO_PORTB_03, //DI }, .mode = SPI_MODE_BIDIR_1BIT, .clk = 1000000, .role = SPI_ROLE_SLAVE, }; #endif
在 sdk/apps/main.c 中函数
user_main()
添加如下工程代码:int user_main() { extern void spi_test_main(void); spi_test_main(); }
编译下载后,PB4接PA3,PB1接PB6,PB2接PB8,PB3接PB7。复位后若打印 “spi test pass” ,则表示spi1主机发送的数据和接收的数据一致。
API参考
SPI 常用相关 API 介绍,具体软件代码见 sdk/bsp/AC638N/src/spi.c
Functions
-
int spi_open(spi_dev spi)
打开spi
- Parameters:
spi – spi句柄
- Returns:
0 成功,< 0 失败
-
int spi_dma_recv(spi_dev spi, void *buf, u32 len)
spi dma接收
- Parameters:
spi – spi句柄
buf – 接收缓冲区基地址
len – 期望接收长度
- Returns:
实际接收长度,< 0表示失败
-
int spi_dma_send(spi_dev spi, const void *buf, u32 len)
spi dma发送
- Parameters:
spi – spi句柄
buf – 发送缓冲区基地址
len – 期望发送长度
- Returns:
实际发送长度,< 0表示失败
-
void spi_dma_set_addr_for_isr(spi_dev spi, void *buf, u32 len, u8 rw)
spi 配置dma,不等待pnd,用于中断
- Parameters:
spi – spi句柄
buf – 缓冲区基地址
len – 期望长度
rw – 1 接收 / 0 发送
- Returns:
null
-
void spi_set_ie(spi_dev spi, u8 en)
中断使能
- Parameters:
spi – spi句柄
en – 1 使能,0 失能
- Returns:
null
-
u8 spi_get_pending(spi_dev spi)
判断中断标志
- Parameters:
spi – spi句柄
- Returns:
0 无png / 1 有png
-
void spi_clear_pending(spi_dev spi)
清除中断标志
- Parameters:
spi – spi句柄
- Returns:
null
-
void spi_set_bit_mode(spi_dev spi, int mode)
设置spi[单向/双向,位数]模式
- Parameters:
spi – spi句柄
mode – 模式: SPI_MODE_BIDIR_1BIT, //支持SPIx(x=0,1,2),全双工,di接收,do发送 SPI_MODE_UNIDIR_1BIT, //支持SPIx(x=0,1,2),半双工,do分时发送/接收 SPI_MODE_UNIDIR_2BIT, //支持SPIx(x=0),半双工,di & do共2bit分时发送/接收 SPI_MODE_UNIDIR_4BIT, //支持SPIx(x=0),半双工,di & do共4bit分时发送/接收
- Returns:
null
-
u8 spi_recv_byte(spi_dev spi, int *err)
接收1个字节
- Parameters:
spi – spi句柄
err – 返回错误信息,若err为非空指针,0 成功,< 0 失败,若为空指针,忽略
- Returns:
接收的字节
-
u8 spi_recv_byte_for_isr(spi_dev spi)
接收1个字节,不等待pnd,用于中断
- Parameters:
spi – spi句柄
- Returns:
接收的字节
-
int spi_send_byte(spi_dev spi, u8 byte)
发送1个字节
- Parameters:
spi – spi句柄
byte – 发送的字节
- Returns:
0 成功,< 0 失败
-
void spi_send_byte_for_isr(spi_dev spi, u8 byte)
发送1个字节,不等待pnd,用于中断
- Parameters:
spi – spi句柄
byte – 发送的字节
- Returns:
null
-
u8 spi_send_recv_byte(spi_dev spi, u8 byte, int *err)
发送并接收1个字节,在8个时钟内完成,仅使用于SPI_MODE_BIDIR_1BIT
- Parameters:
spi – spi句柄
byte – 发送的字节
err – 返回错误信息,若err为非空指针,0 成功,< 0 失败,若为空指针,忽略
- Returns:
接收的字节
-
int spi_set_baud(spi_dev spi, u32 baud)
设置波特率
- Parameters:
spi – spi句柄
baud – 波特率
- Returns:
0 成功,< 0 失败
-
u32 spi_get_baud(spi_dev spi)
获取波特率
- Parameters:
spi – spi句柄
- Returns:
波特率
-
void spi_close(spi_dev spi)
关闭spi
- Parameters:
spi – spi句柄
- Returns:
null