本文主要是介绍基于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模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!