基于TI SYSBIOS GIO 接口封装的SPI DMA模式

2024-02-28 16:38

本文主要是介绍基于TI SYSBIOS GIO 接口封装的SPI DMA模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基于TI SYSBIOS GIO 接口封装的SPI DMA模式

硬件:TMS320C6748 (创龙开发板)
bsp: bios_6_37_03_30

注意:
DMA模式需要先使能EMDA3 TC/CC 通道。初始化EDMA3,
然后再创建SPi handle,
app.cfg 中要静态创建spi1设备并添加ECM 也就是EventCombiner,
var iomFxns5 = “Spi_IOMFXNS”;
var initFxn5 = “user_spi1_init”;
var deviceParams5 = “spiParams”;
var deviceId5 = 1;
GIO.addDeviceMeta("/spi1", iomFxns5, initFxn5, deviceId5, deviceParams5);
ECM.eventGroupHwiNum[0] = 7;
ECM.eventGroupHwiNum[1] = 8;
ECM.eventGroupHwiNum[2] = 9;
ECM.eventGroupHwiNum[3] = 10;

C6748 SPI 除了chip指定的几个片选功能引脚(SPIx_CSn0~7)外,还支持普通GPIO作为片选引脚,
如果使用SPIx_CSn0~7 只需在初始化接口的第二个参数中指定即可,后面两个参数不生效
如果使用普通GPIO作为cs pin, 第二个参数指定TLFS_HAL_SPI_CS_GPIO, 并在后面两个参数中指定具体的gpio, 具体的bank num和 pinnum (bank中的index)请查询手册,

int tlfs_hal_spi_init(TLFS_HAL_SPI_e spi_port, TLFS_HAL_SPI_CS_e cs, unsigned int gpiobank_num, unsigned int Gpio_Pin);

具体代码如下, 仅供参考,有问题还请指出,

/** tlfs_hal_spi.h**  Created on: 2021-12-3*      Author: Bruce Su*/#ifndef TLFS_HAL_SPI_H_
#define TLFS_HAL_SPI_H_#define TLFS_SPI_TRANSFER_MAX_LEN   (16)typedef enum __tlfs_hal_spi__
{TLFS_HAL_SPI0 = 0,TLFS_HAL_SPI1,TLFS_HAL_SPI_MAX
}TLFS_HAL_SPI_e;typedef enum __tlfs_hal_spi_cs__
{TLFS_HAL_SPI_CS0 = 0,TLFS_HAL_SPI_CS1,TLFS_HAL_SPI_CS2,TLFS_HAL_SPI_CS3,TLFS_HAL_SPI_CS4,TLFS_HAL_SPI_CS5,TLFS_HAL_SPI_CS6,TLFS_HAL_SPI_CS7,TLFS_HAL_SPI_CS_GPIO,TLFS_HAL_SPI_CS_MAX
}TLFS_HAL_SPI_CS_e;/*
* cs  = TLFS_HAL_SPI_CS_GPIO 时,gpiobank_num 和 Gpio_Pin 才有效
* GP3[13]  gpiobank_num = 3    Gpio_Pin = 13   gpio num = 3* 16 + 13 + 1 = 62
*/
int tlfs_hal_spi_init(TLFS_HAL_SPI_e spi_port, TLFS_HAL_SPI_CS_e cs, unsigned int gpiobank_num, unsigned int Gpio_Pin);
int tlfs_hal_spi_write(TLFS_HAL_SPI_e spi_port, unsigned char* data, unsigned int len);
int tlfs_hal_spi_read(TLFS_HAL_SPI_e spi_port, unsigned char* data, unsigned int len);#endif /* TLFS_HAL_SPI_H_ */
/** tlfs_hal_spi.c**  Created on: 2021-12-3*      Author: Bruce Su*/#include <xdc/std.h>
#include <string.h>
#include <stdio.h>
#include <xdc/runtime/Memory.h>
#include <xdc/runtime/Log.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/log.h>
#include <ti/sysbios/knl/task.h>
#include <ti/sysbios/io/GIO.h>
#include <ti/sysbios/io/iom.h>#include <SPI/include/Spi.h>
#include <GPIO/include/Gpio.h>
#include <PSC/Include/Psc.h>#include <edma3_drv.h>
#include <CSLR/cslr_spi.h>
#include "tlfs_hal_spi.h"
#include "TL6748.h"#define SPI1_HW_NUM   (13)
#define SPI1_SPEED    (12000000)typedef struct _tlfs_spi_handle_ {GIO_Handle spi_Handle;unsigned int cs_gpio_num;TLFS_HAL_SPI_CS_e cs;Bool inited;
}TLFS_SPI_Handle_s;static TLFS_SPI_Handle_s tlfs_spi_handle[TLFS_HAL_SPI_MAX];
extern EDMA3_DRV_Handle hEdma;/* Buffer alignement is required when working in DMA Mode */
/* max command length is 4 (opcode + 3 bytes address) + max trnsfer size )    */
#pragma DATA_ALIGN(spi1loopWrite, 128);
Uint8  spi1loopWrite[TLFS_SPI_TRANSFER_MAX_LEN];/* Buffer alignement is required when working in DMA Mode */
#pragma DATA_ALIGN(spi1loopRead, 128);
Uint8  spi1loopRead[TLFS_SPI_TRANSFER_MAX_LEN];#pragma DATA_ALIGN(spi0loopWrite, 128);
Uint8  spi0loopWrite[TLFS_SPI_TRANSFER_MAX_LEN];/* Buffer alignement is required when working in DMA Mode */
#pragma DATA_ALIGN(spi0loopRead, 128);
Uint8  spi0loopRead[TLFS_SPI_TRANSFER_MAX_LEN];/* Global SPI init config data structure */
Spi_Params       spiParams;
static int spi_init_done = 0;EDMA3_DRV_Handle edma3init(unsigned int edma3Id, EDMA3_DRV_Result *);static unsigned int hal_spi_cs_to_csl_cs(TLFS_HAL_SPI_CS_e cs)
{switch(cs){case TLFS_HAL_SPI_CS0:return CSL_SPI_SPIPC0_SCS0FUN0_MASK;case TLFS_HAL_SPI_CS1:return CSL_SPI_SPIPC0_SCS0FUN1_MASK;case TLFS_HAL_SPI_CS2:return CSL_SPI_SPIPC0_SCS0FUN2_MASK;case TLFS_HAL_SPI_CS3:return CSL_SPI_SPIPC0_SCS0FUN3_MASK;case TLFS_HAL_SPI_CS4:return CSL_SPI_SPIPC0_SCS0FUN4_MASK;case TLFS_HAL_SPI_CS5:return CSL_SPI_SPIPC0_SCS0FUN5_MASK;case TLFS_HAL_SPI_CS6:return CSL_SPI_SPIPC0_SCS0FUN6_MASK;case TLFS_HAL_SPI_CS7:return CSL_SPI_SPIPC0_SCS0FUN7_MASK ;case TLFS_HAL_SPI_CS_GPIO:return 0;default:return CSL_SPI_SPIPC0_SCS0FUN0_MASK;}
}static void spi_early_init(void)
{if(spi_init_done == 0){spi_init_done = 1;Psc_ModuleClkCtrl(Psc_DevId_0, CSL_PSC_CC0, TRUE);Psc_ModuleClkCtrl(Psc_DevId_0, CSL_PSC_TC0, TRUE);Psc_ModuleClkCtrl(Psc_DevId_0, CSL_PSC_TC1, TRUE);Psc_ModuleClkCtrl(Psc_DevId_1, CSL_PSC_CC1, TRUE);Psc_ModuleClkCtrl(Psc_DevId_1, CSL_PSC_GPIO, TRUE);Spi_init();EDMA3_DRV_Result	edmaResult		= 0;// EDMA3 初始化if(hEdma == NULL)hEdma = edma3init(0, &edmaResult);memset(tlfs_spi_handle, 0, TLFS_HAL_SPI_MAX * sizeof(TLFS_SPI_Handle_s));}
}void user_spi1_init()
{spiParams = Spi_PARAMS;spiParams.hwiNumber = SPI1_HW_NUM;spiParams.opMode = Spi_OpMode_DMAINTERRUPT;spiParams.outputClkFreq     = SPI1_SPEED;spiParams.loopbackEnabled   = FALSE;spiParams.edmaHandle        = NULL;spiParams.spiHWCfgData.configDatafmt[0].charLength   = 8;spiParams.spiHWCfgData.configDatafmt[0].clkHigh      = TRUE ;spiParams.spiHWCfgData.configDatafmt[0].lsbFirst     = FALSE;spiParams.spiHWCfgData.configDatafmt[0].oddParity    = FALSE;spiParams.spiHWCfgData.configDatafmt[0].parityEnable = FALSE ;spiParams.spiHWCfgData.configDatafmt[0].phaseIn      = FALSE ;spiParams.spiHWCfgData.configDatafmt[0].waitEnable   = FALSE;spiParams.spiHWCfgData.intrLevel     = TRUE;Psc_ModuleClkCtrl(Psc_DevId_1, CSL_PSC_SPI1, TRUE);spi_early_init();
}int tlfs_hal_spi_init(TLFS_HAL_SPI_e spi_port, TLFS_HAL_SPI_CS_e cs, unsigned int gpiobank_num, unsigned int Gpio_Pin)
{if(spi_port >= TLFS_HAL_SPI_MAX || spi_port < TLFS_HAL_SPI0) return -1;if(tlfs_spi_handle[spi_port].inited) return 0;SPIPinMuxSetup(spi_port);Error_Block 		eb;Spi_ChanParams      chanParams;GIO_Params 			ioParams;/** Initialize channel attributes.*/GIO_Params_init(&ioParams);Error_init(&eb);if(cs == TLFS_HAL_SPI_CS_GPIO){Gpio_Handle 	gpio0 = NULL;tlfs_spi_handle[spi_port].cs_gpio_num = gpiobank_num * 16 + Gpio_Pin + 1;Gpio_PinCmdArg    pinCmdArg;Gpio_Params     gpioParams = Gpio_PARAMS;gpioParams.instNum = 0;gpioParams.BankParams[gpiobank_num].inUse = Gpio_InUse_No;gpioParams.BankParams[gpiobank_num].hwiNum  = 8u;gpioParams.BankParams[gpiobank_num].PinConfInfo[Gpio_Pin].inUse = Gpio_InUse_No;/* open the GPIO driver to get a handle to it */gpio0 = Gpio_open(&gpioParams);if(gpio0 == NULL) return -1;chanParams.hGpio = gpio0;pinCmdArg.pin   = tlfs_spi_handle[spi_port].cs_gpio_num;pinCmdArg.value = Gpio_Direction_Output;Gpio_setPinDir(gpio0, &pinCmdArg);}else{if(spi_port == TLFS_HAL_SPI1)SPI1CSPinMuxSetup(cs);elseSPI0CSPinMuxSetup(cs);}chanParams.hEdma 	= hEdma;ioParams.chanParams = &chanParams;char spi_name[8] = {'\0'};sprintf(spi_name, "/spi%d", spi_port);/* create SPI channel for transmission */tlfs_spi_handle[spi_port].spi_Handle = GIO_create(spi_name, GIO_INOUT, &ioParams, &eb);if (NULL == tlfs_spi_handle[spi_port].spi_Handle){return -1;}tlfs_spi_handle[spi_port].cs = cs;tlfs_spi_handle[spi_port].inited = TRUE;return 0;
}int tlfs_hal_spi_write(TLFS_HAL_SPI_e spi_port, unsigned char* data, unsigned int len)
{SizeT	 size = 0;Spi_DataParam       dataparam;unsigned char* spi_writebuf = NULL;if((data == NULL) || (tlfs_spi_handle[spi_port].inited == FALSE) || (len > TLFS_SPI_TRANSFER_MAX_LEN)) return -1;if(spi_port == TLFS_HAL_SPI0){spi_writebuf = spi0loopWrite;}else{spi_writebuf = spi1loopWrite;}memset(&dataparam, 0x00, sizeof(Spi_DataParam));memcpy(spi_writebuf, data, len);dataparam.bufLen       = len;dataparam.inBuffer     = NULL;dataparam.outBuffer    = spi_writebuf;dataparam.flags    = Spi_CSHOLD;dataparam.dataFormat   = Spi_DataFormat_0;dataparam.chipSelect = hal_spi_cs_to_csl_cs(tlfs_spi_handle[spi_port].cs);if(tlfs_spi_handle[spi_port].cs == TLFS_HAL_SPI_CS_GPIO){dataparam.flags    |= Spi_GPIO_CS;dataparam.gpioPinNum = tlfs_spi_handle[spi_port].cs_gpio_num;}size = dataparam.bufLen;GIO_submit(tlfs_spi_handle[spi_port].spi_Handle, IOM_WRITE, &dataparam, &size, NULL);return 0;
}int tlfs_hal_spi_read(TLFS_HAL_SPI_e spi_port, unsigned char* data, unsigned int len)
{SizeT	 size = 0;Spi_DataParam       dataparam;unsigned char* spi_readbuf = NULL;if((data == NULL) || (tlfs_spi_handle[spi_port].inited == FALSE) || (len > TLFS_SPI_TRANSFER_MAX_LEN)) return -1;if(spi_port == TLFS_HAL_SPI0){spi_readbuf = spi0loopRead;}else{spi_readbuf = spi1loopRead;}memset(&dataparam, 0x00, sizeof(Spi_DataParam));memset(spi1loopRead, 0 ,TLFS_SPI_TRANSFER_MAX_LEN);dataparam.bufLen       = len;dataparam.inBuffer     = spi_readbuf;dataparam.outBuffer    = NULL;dataparam.flags    = Spi_CSHOLD;dataparam.dataFormat   = Spi_DataFormat_0;dataparam.chipSelect = hal_spi_cs_to_csl_cs(tlfs_spi_handle[spi_port].cs);if(tlfs_spi_handle[spi_port].cs == TLFS_HAL_SPI_CS_GPIO){dataparam.flags    |= Spi_GPIO_CS;dataparam.gpioPinNum = tlfs_spi_handle[spi_port].cs_gpio_num;}size = dataparam.bufLen;GIO_submit(tlfs_spi_handle[spi_port].spi_Handle, IOM_WRITE, &dataparam, &size, NULL);memcpy(data, spi_readbuf, len);return 0;
}

这篇关于基于TI SYSBIOS GIO 接口封装的SPI DMA模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/756023

相关文章

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Nginx location匹配模式与规则详解

《Nginxlocation匹配模式与规则详解》:本文主要介绍Nginxlocation匹配模式与规则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、环境二、匹配模式1. 精准模式2. 前缀模式(不继续匹配正则)3. 前缀模式(继续匹配正则)4. 正则模式(大

usb接口驱动异常问题常用解决方案

《usb接口驱动异常问题常用解决方案》当遇到USB接口驱动异常时,可以通过多种方法来解决,其中主要就包括重装USB控制器、禁用USB选择性暂停设置、更新或安装新的主板驱动等... usb接口驱动异常怎么办,USB接口驱动异常是常见问题,通常由驱动损坏、系统更新冲突、硬件故障或电源管理设置导致。以下是常用解决

鸿蒙中Axios数据请求的封装和配置方法

《鸿蒙中Axios数据请求的封装和配置方法》:本文主要介绍鸿蒙中Axios数据请求的封装和配置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.配置权限 应用级权限和系统级权限2.配置网络请求的代码3.下载在Entry中 下载AxIOS4.封装Htt

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

go中空接口的具体使用

《go中空接口的具体使用》空接口是一种特殊的接口类型,它不包含任何方法,本文主要介绍了go中空接口的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录接口-空接口1. 什么是空接口?2. 如何使用空接口?第一,第二,第三,3. 空接口几个要注意的坑坑1:坑2:坑3:接口-空接口1. 什么是空接

SpringBoot中封装Cors自动配置方式

《SpringBoot中封装Cors自动配置方式》:本文主要介绍SpringBoot中封装Cors自动配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot封装Cors自动配置背景实现步骤1. 创建 GlobalCorsProperties

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M

Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)

《Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)》:本文主要介绍Java导入、导出excel的相关资料,讲解了使用Java和ApachePOI库将数据导出为Excel文件,包括... 目录前言一、引入Apache POI依赖二、用法&步骤2.1 创建Excel的元素2.3 样式和字体2.

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3