C6000系列DSP的GPIO模块

最近一直在做DSP与FPGA之间的视频传输工作,使用的通信方式是EDMA,为了系统的介绍通过EDMA方式在DSP与FPGA之间实现数据传输。


首先介绍一下DSP-C6455中的GPIO与中断系统。以后再介绍DSP强大的EDMA模块,以及具体的数据传输实现。


(注:  其实EDMA是C6455芯片中的一个模块,可以认为其是芯片内部的一个”协处理器”)



---------------------------华丽分割----------------------------------



背景

使用DSP+FPGA搭建的嵌入式系统进行视频采集,编解码,传输无疑是一个不错的选择。使用FPGA系统进行视频采集,DSP进行视频处理需要了解一下知识:

  • 1.   DSP-C6000系列的中断与GPIO系统
  • 2.   DSP-C6000系列的EDMA模块
  • 3.   FPGA的乒乓RAM
  • 4.   一种视频格式(例如VGA,PAL等)
  • 5.   视频处理算法

 

      本文将介绍DSP C6000系列的GPIO系统(针对C6455)



--------------------------- 华丽分割 ----------------------------------



C6455的GPIO

      TMS320C6455中共有16个通用输入输出管脚。每一个管脚都可以单独进行配置成如下功能之一:

  •       通用输入管脚Input
  •       通用输出管脚Output
  •       中断&EDMA事件 管脚

---------------------------华丽分割----------------------------------


GPIO框图

      首先看一下GPIO的框图:



通过查看GPIO框图,我们可以得出许多信息:

  • DIR寄存器控制GPIO管脚是输入还是输出,其中,对应bit置0表示该管脚配置为输出管脚;对应bit置1表示该管脚配置为输入管脚
  • 若一个GPIO管脚配置为Output,给SET_DATA寄存器对应位置1,将使该管脚输出高电平,给CLR_DATA寄存器对应位置1,将使该管脚输出低电平。需要注意的是:向SET_DATA和CLR_DATA中写入0无作用
  • 若一个GPIO管脚配置为Input,可以通过读取IN_DATA寄存器中的对应位来获得管脚的状态。且向SET_DATA和CLR_DATA中写入0无作用
  • 若一个GPIO管脚配置为中断&EDMA事件模式,此时可以忽略该管脚的Input/Output配置。可以通过置位SET_RIS_TRIG和SET_FAL_TRIG寄存器的相应bit把GPIO管脚配置为中断/事件触发方式。如下图所示:


由于C64+CPU无法直接访问RIS_TRIGFAL_TRIG寄存器,若要访问中断模式的配置状态,可以通过读取SET_RIS_TRIGSET_FAL_TRIG)或者CLR_RIS_TRIG(CLR_FAL_TRIG)来获取。



---------------------------华丽分割----------------------------------


GPIO寄存器组       
C6455中GPIO的寄存器组如下所示:

其中,后面9个不再介绍了。唯独第一个寄存器之前没有介绍到

查看官方文档:


可以看出,只有该寄存器最低位置1时GPIO管脚才可以作为中断源。所以,只要你使用GPIO管脚中的某一个作为系统的中断源,那么该位必须置1。


---------------------------华丽分割----------------------------------


GPIO管脚复用

      此外,使用GPIO时,还需要考虑到对应芯片的管脚复用问题,以6455为例,GPIO管脚复用情况如下图示:



可见,16GPIO管脚中有大半是可以复用的。可以通过配置6455的外设配置寄存器来使能GPIO模块。即把6455中的PERCFG0寄存器中GPIO对应位置1,如下图示:







---------------------------华丽分割----------------------------------


GPIO之CSL库

      使用CSL库的API函数配置DSP显然比逐一配置寄存器方面且容易理解。下面介绍一下如何使用CSL库把DSP的GPIO4配置成中断模式。

     

  • 第一步:使能GPIO模块

      使能之前,首先要解除锁,即向PERLOCK寄存器写入0x0F0A0B00,然后把PERCFG0寄存器中GPIO对应位置1。代码如下:

  1. <SPAN style="FONT-FAMILY: 'Microsoft YaHei'">Bool   gpioEn;  
  2. CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERLOCK,DEV_PERLOCK_LOCKVAL, UNLOCK);  
  3.    
  4. CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG0, DEV_PERCFG0_GPIOCTL, ENABLE);  
  5.   
  6. do {  
  7.        gpioEn = (Bool)CSL_FEXT(((CSL_DevRegs*)CSL_DEV_REGS)->PERSTAT0,   
  8.                                  DEV_PERSTAT0_GPIOSTAT);  
  9. while (gpioEn != TRUE);  
  10. </SPAN>  
Bool	gpioEn;
CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERLOCK,DEV_PERLOCK_LOCKVAL, UNLOCK);
 
CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG0, DEV_PERCFG0_GPIOCTL, ENABLE);

do {
       gpioEn = (Bool)CSL_FEXT(((CSL_DevRegs*)CSL_DEV_REGS)->PERSTAT0, 
                                 DEV_PERSTAT0_GPIOSTAT);
} while (gpioEn != TRUE);

  • 第二步:初始化GPIO模块

  1. <SPAN style="FONT-FAMILY: 'Microsoft YaHei'">CSL_Status                    status;  
  2. CSL_GpioContext               pContext;  
  3. status   =     CSL_gpioInit(&pContext);</SPAN>  
CSL_Status                    status;
CSL_GpioContext               pContext;
status   =     CSL_gpioInit(&pContext);

 

  • 第三步:打开GPIO模块
  • 第四步:使能GPIO管脚作为中断源的功能
  • 第五步:配置GPIO-PIN4的属性:方向,中断触发方式



---------------------------华丽分割----------------------------------



完整的配置代码如下所示:


  1. <SPAN style="FONT-FAMILY: 'Microsoft YaHei'">/*----------------------------------------------------------------------------------- 
  2.  *  
  3.  *                  初始化GPIO      
  4.  *  
  5.  -----------------------------------------------------------------------------------*/  
  6. void Init_GPIO()  
  7. {  
  8.     Bool                        gpioEn;  
  9.     CSL_Status                  status;  
  10.     CSL_GpioContext             pContext;  
  11.     CSL_GpioHandle              hGpio;  
  12.     CSL_GpioObj                 gpioObj;  
  13.     CSL_GpioHwSetup             hwSetup;  
  14.     CSL_GpioPinConfig           config;  
  15. //    CSL_GpioPinNum            pinNum;   
  16.   
  17.     /* Unlock the control register */  
  18.     CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERLOCK, DEV_PERLOCK_LOCKVAL,   
  19.               UNLOCK);  
  20.                  
  21.     /* Enable the GPIO */  
  22.     CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG0, DEV_PERCFG0_GPIOCTL,   
  23.               ENABLE);  
  24.   
  25.     do {  
  26.         gpioEn = (Bool) CSL_FEXT(((CSL_DevRegs*)CSL_DEV_REGS)->PERSTAT0,   
  27.                                    DEV_PERSTAT0_GPIOSTAT);  
  28.     } while (gpioEn != TRUE);  
  29.   
  30.         /* Initialize the GPIO CSL module */  
  31.     status = CSL_gpioInit(&pContext);  
  32.   
  33. #ifdef SHOW_PRINTF   
  34.     if (status != CSL_SOK) {  
  35.         printf("GPIO: Initialization error.\n");  
  36.         return;  
  37.     }  
  38.     else {  
  39.         printf("GPIO: Module Initialized.\n");  
  40.     }  
  41. #endif   
  42.   
  43.     /* Open the CSL module */  
  44.     hGpio = CSL_gpioOpen(&gpioObj, CSL_GPIO, NULL, &status);  
  45. #ifdef SHOW_PRINTF   
  46.     if ((hGpio == NULL) || (status != CSL_SOK)) {  
  47.         printf("GPIO: Error opening the instance.\n");  
  48.         return;  
  49.     }  
  50.     else {  
  51.         printf("GPIO: Module instance opened.\n");  
  52.     }  
  53. #endif   
  54.   
  55.     /* Setup hardware parameters */  
  56.     hwSetup.extendSetup = NULL;  
  57.       
  58.     /* Setup the General Purpose IO */  
  59.     status = CSL_gpioHwSetup(hGpio, &hwSetup);  
  60.   
  61.     /* Enable the bank interrupt */  
  62.     status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_BANK_INT_ENABLE, NULL);  
  63. #ifdef SHOW_PRINTF   
  64.     if (status != CSL_SOK) {  
  65.         printf("GPIO: Command to enable bank interrupt... Failed.\n");  
  66.     }  
  67.     else {  
  68.         printf("GPIO: Command to enable bank interrupt... successful.\n");  
  69.     }  
  70. #endif   
  71.   
  72.     /* Configure pin 4 to generate an interrupt on Rising Edge, and 
  73.      * configure it as an input, then set the data High (Low->High). 
  74.      * Set Trigger:  
  75.      */  
  76.     config.pinNum       = CSL_GPIO_PIN4;  
  77.     config.trigger      = CSL_GPIO_TRIG_RISING_EDGE;  
  78.     config.direction    = CSL_GPIO_DIR_INPUT;  
  79.   
  80.     /* configure the gpio pin 4 */  
  81.     status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_CONFIG_BIT, &config);  
  82. #ifdef SHOW_PRINTF   
  83.     if (status != CSL_SOK) {  
  84.         printf("GPIO: GPIO pin configuration error.\n");  
  85.         return;  
  86.     }  
  87.     else {  
  88.         printf("GPIO: GPIO pin configuration successful.\n");  
  89.     }  
  90. #endif   
  91. }</SPAN>  
/*-----------------------------------------------------------------------------------
 * 
 * 					初始化GPIO		
 * 
 -----------------------------------------------------------------------------------*/
void Init_GPIO()
{
 	Bool  						gpioEn;
    CSL_Status              	status;
    CSL_GpioContext         	pContext;
	CSL_GpioHandle 				hGpio;
    CSL_GpioObj             	gpioObj;
    CSL_GpioHwSetup             hwSetup;
    CSL_GpioPinConfig          	config;
//    CSL_GpioPinNum          	pinNum;

    /* Unlock the control register */
    CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERLOCK, DEV_PERLOCK_LOCKVAL, 
              UNLOCK);
               
    /* Enable the GPIO */
    CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG0, DEV_PERCFG0_GPIOCTL, 
              ENABLE);

    do {
        gpioEn = (Bool) CSL_FEXT(((CSL_DevRegs*)CSL_DEV_REGS)->PERSTAT0, 
                                   DEV_PERSTAT0_GPIOSTAT);
    } while (gpioEn != TRUE);

	    /* Initialize the GPIO CSL module */
    status = CSL_gpioInit(&pContext);

#ifdef SHOW_PRINTF
    if (status != CSL_SOK) {
        printf("GPIO: Initialization error.\n");
        return;
    }
	else {
        printf("GPIO: Module Initialized.\n");
    }
#endif

    /* Open the CSL module */
    hGpio = CSL_gpioOpen(&gpioObj, CSL_GPIO, NULL, &status);
#ifdef SHOW_PRINTF
    if ((hGpio == NULL) || (status != CSL_SOK)) {
        printf("GPIO: Error opening the instance.\n");
        return;
    }
	else {
        printf("GPIO: Module instance opened.\n");
    }
#endif

    /* Setup hardware parameters */
    hwSetup.extendSetup = NULL;
    
    /* Setup the General Purpose IO */
    status = CSL_gpioHwSetup(hGpio, &hwSetup);

    /* Enable the bank interrupt */
    status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_BANK_INT_ENABLE, NULL);
#ifdef SHOW_PRINTF
    if (status != CSL_SOK) {
        printf("GPIO: Command to enable bank interrupt... Failed.\n");
    }
	else {
        printf("GPIO: Command to enable bank interrupt... successful.\n");
    }
#endif

    /* Configure pin 4 to generate an interrupt on Rising Edge, and
     * configure it as an input, then set the data High (Low->High).
     * Set Trigger: 
     */
    config.pinNum 		= CSL_GPIO_PIN4;
    config.trigger 		= CSL_GPIO_TRIG_RISING_EDGE;
    config.direction 	= CSL_GPIO_DIR_INPUT;

    /* configure the gpio pin 4 */
    status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_CONFIG_BIT, &config);
#ifdef SHOW_PRINTF
    if (status != CSL_SOK) {
        printf("GPIO: GPIO pin configuration error.\n");
        return;
    }
    else {
        printf("GPIO: GPIO pin configuration successful.\n");
    }
#endif
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PIO(General-Purpose Input/Output)——通用输入/输出口;       DSP28335 GPIO模块分为三类IO口:PORTA(0-31),PORTB(32-63),PORTC(64-87) 对GPIO模块的设置主要通过三类寄存器来完成,分别是:控制寄存器、数据寄存器、中断寄存器。 1、控制寄存器   GPxCTRL;    // GPIO x Control Register (GPIO0 to 31)               //设置采样窗周期T=2*GPXCTRL*Tsysclk;   GPxQSEL1;   // GPIO x Qualifier Select 1 Register (GPIO0 to 15)(32-47)               GPxQSEL2;   // GPIO x Qualifier Select 2 Register (GPIO16 to 31)(48-63)               //每两位控制一个引脚,确定是3周期采样还是6周期采样或者不用采样   GPxMUX1;    // GPIO x Mux 1 Register (GPIO0 to 15)(32-47)(64-79)   GPxMUX2;    // GPIO x Mux 2 Register (GPIO16 to 31)(48-63)(80-95)               //配置各个引脚的功能,0:I/O功能,1:外设功能。   GPxDIR;     // GPIO x Direction Register (GPIO0 to 31)(32-63)(64-95)               //配置每个引脚是输入还是输出,0:数字量输入;1:数字量输出。   GPxPUD;     // GPIO x Pull Up Disable Register (GPIO0 to 31)(32-63)(64-95)               //使能或禁止内部上拉 0:开启上拉,1:禁止上拉 2、数据寄存器   GPxDAT;     // GPIO Data Register (GPIO0 to 31)(32-63)(64-95)   GPxSET;     // GPIO Data Set Register (GPIO0 to 31)(32-63)(64-95)——置位   GPxCLEAR;   // GPIO Data Clear Register (GPIO0 to 31)(32-63)(64-95)   GPxTOGGLE;  // GPIO Data Toggle Register (GPIO0 to 31)(32-63)(64-95)—反转
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值