基于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);
		else
			SPI0CSPinMuxSetup(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;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值