分享iCore4T移植RT-Thread过程的点点滴滴——DAY 13 高手请略过,如有错误请多多批评指点! iCore4T上,RAM通过SPI4总线与FPGA通信,今天,我将给大家分享RTT添加SPI总线和FPGA驱动,最后实现FPGA的读写测试。 1、修改board文件夹下kconfig文件,在menu "Onboard Peripheral Drivers"中添加配置FPGA选项,在menu "On-chip Peripheral Drivers"配置SPI总线并在menuconfig菜单配置中勾选。 2、在文件路径stm32\libraries\HAL_Drivers下,我们修改SConscript文件,将drv_spi_fpga.c源文件添加到编译脚本中去。 3、drv_spi_fpga.c文件内容贴在下面。 /*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-02-17 zh. first version
*/
#include <board.h>
#include <drv_spi.h>
#include <rtdevice.h>
#include <rthw.h>
#include <finsh.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef BSP_USING_SPI_FPGA
/* fpga command */
#define FPGA_READ_ID_CMD 0x01
#define FPGA_WRITE_LEN_CMD 0x02
#define FPGA_WRITE_STATE_CMD 0x03
#define FPGA_WRITE_CMD 0x04
#define FPGA_READ_LEN_CMD 0x05
#define FPGA_READ_STATE_CMD 0x06
#define FPGA_READ_CMD 0x07
/* spi bus device name*/
#define FPGA_SPI_DEVICE_NAME "spi4"
/* spi device name*/
#define FPGA_DEVICE_NAME "FPGA"
struct rt_spi_device *spi4_device;
static int spi_write_read_test(void)
{
rt_uint32_t i;
rt_uint32_t temp;
rt_size_t t_size = 0;
rt_uint8_t send_buffer[1028];
rt_uint8_t recv_buffer[1028];
rt_uint8_t error = 0;
float speed;
/* write command */
send_buffer[0] = FPGA_WRITE_CMD;
send_buffer[1] = 0x00;
send_buffer[2] = 0x00;
/* pseudo command */
send_buffer[1027] = 0x00;
for(i = 0;i < 1024;i ++)
{
send_buffer[i + 3] = i % 256;
}
// t_size = rt_spi_transfer(spi4_device,send_buffer,recv_buffer,sizeof(send_buffer));
temp = HAL_GetTick();
for(i = 0;i < 10240;i ++)
{
t_size = rt_spi_transfer(spi4_device,send_buffer,recv_buffer,sizeof(send_buffer));
}
temp = HAL_GetTick() - temp;
if(t_size != sizeof(send_buffer))
{
rt_kprintf("fpga write fail!\n");
return RT_ERROR;
}
rt_thread_mdelay(100);
//read_command
send_buffer[0] = FPGA_READ_CMD;
send_buffer[1] = 0x00;
send_buffer[2] = 0x00;
/* pseudo command */
send_buffer[3] = 0x00;
memset(recv_buffer,0,sizeof(recv_buffer));
t_size = rt_spi_transfer(spi4_device,send_buffer,recv_buffer,sizeof(send_buffer));
if(t_size != sizeof(send_buffer))
{
rt_kprintf("fpga read fail!\n");
return RT_ERROR;
}
else
{
for(i = 0;i < 1024;i ++)
{
if(recv_buffer[i+4] != i%256)
{
error ++;
break;
}
}
}
if(error)
{
rt_kprintf("fpga test fail!\n");
}
else
{
speed = 10000./temp;
temp = speed * 100;
rt_kprintf("fpga test ok!\n");
// rt_kprintf("speed : %d.%02dMBytes/s\n",temp/100,temp%100);
}
return RT_EOK;
}
MSH_CMD_EXPORT(spi_write_read_test,fpga);
static int rt_hw_spi_fpga_probe(void)
{
struct rt_spi_configuration cfg;
rt_size_t t_size = 0;
rt_uint8_t send_buffer[5];
rt_uint8_t recv_buffer[5];
rt_uint8_t fpga_id;
/* find spi4 device*/
spi4_device = (struct rt_spi_device *)rt_device_find(FPGA_DEVICE_NAME);
if(spi4_device == RT_NULL)
{
rt_kprintf("ERROR: SPI device %s not found!\n", FPGA_DEVICE_NAME);
return RT_ERROR;
}
/* config spi4 bus */
cfg.data_width = 8;
cfg.max_hz = 130*1000*1000;
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_3 | RT_SPI_MSB;
rt_spi_configure(spi4_device, &cfg);
/* get fpga ID*/
send_buffer[0] = 0x01;
t_size = rt_spi_transfer(spi4_device,send_buffer,recv_buffer,sizeof(send_buffer));
if(t_size != sizeof(send_buffer))
{
rt_kprintf("[FPGA] probe fail!");
return RT_ERROR;
}
else
{
rt_kprintf("[FPGA] probe ok! ID is 0x%02X\n",recv_buffer[4]);
fpga_id = recv_buffer[4];
return fpga_id;
}
}
static int rt_hw_spi4_fpga_init(void)
{
__HAL_RCC_GPIOE_CLK_ENABLE();
/* attach fpga to spi bus */
rt_hw_spi_device_attach(FPGA_SPI_DEVICE_NAME, FPGA_DEVICE_NAME, GPIOE, GPIO_PIN_4);
/* probe fpga */
rt_hw_spi_fpga_probe();
return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_spi4_fpga_init);
static int fpga(int argc, char **argv)
{
int result = RT_EOK;
if (argc > 1)
{
if(!strcmp(argv[0],"fpga"))
{
if (!strcmp(argv[1], "probe"))
{
if (argc == 2)
{
rt_hw_spi_fpga_probe();
}
else
{
rt_kprintf("Bad command. Please enter 'fpga' for help\n");
}
}
else if (!strcmp(argv[1], "test"))
{
if (argc == 2)
{
spi_write_read_test();
}
else
{
rt_kprintf("Bad command. Please enter 'fpga' for help\n");
}
}
else
{
rt_kprintf("Bad command. Please enter 'fpga' for help\n");
}
}
else
{
rt_kprintf("Bad command. Please enter 'eeprom' for help\n");
}
}
else
{
rt_kprintf("Usage: \n");
rt_kprintf("fpga probe - read fpga id value\n");
rt_kprintf("fpga test - write & read test fpga\n");
result = -RT_ERROR;
}
return result;
}
MSH_CMD_EXPORT(fpga, fpga function);
#endif /* BSP_USING_SPI_FPGA */
4、在board\CubeMX_Config目录下,打开CubeMX_Config.ioc工程。配置SPI4为Full-Duplex Master模式,将GPIO设置为Very High,点击GENERATE CODE。 5、使用命令scons --target=mdk5,生成MDK5工程,在工程文件stm32h7xx_hal_conf.h中,取消SPI库文件注释。 6、先将iCore4T_FPGA_17:基于SPI总线的ARM与FPGA通信实验中FPGA程序下载到fpga中。 7、将工程编译,烧录,就可以进行FPGA读写测试了。打开终端,选择对应COM口,比特率115200,可以看到系统启动信息,设备列表中有SPI4总线,FPGA设备。执行命令fpga probe探测到FPGA的ID为0x01,执行fpga test进行FPGA读写测试。 至此说明我们的RAM-FPGA通信成功。
8、源代码
源代码可以稳步这里下载:
链接:https://pan.baidu.com/s/1fcLU4WaRDlgr0mNYwZj1Yg 提取码:zstq
|