This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320C6748: GPIO Read/Write Code

Part Number: TMS320C6748

Tool/software: Code Composer Studio

We're trying to read from GPIO pins on the TMS320C6748 dev board, so we currently have a power source connected to pin 3 on J14, with the code below running in debug mode in CCS 7. It's not sensing the change in voltage. Is there a problem with our code configuration of the GPIO pins? Where on this board would we be able to access GPIO pins? Additionally, we know the switches 5,6,7,8 are also connected to GPIO somehow, could someone elaborate on that please?

Thanks in advance for your answer!

/**

* main.c
*/

//#include "hw_emifa2.h"
//#include "hw_types.h"
//#include "soc_C6748.h"
//#include "uartStdio.h"
//#include "interrupt.h"
//#include "emifa.h"
//#include "evmC6748.h"
#include "hw_gpio.h"
#include "gpio.h"
#include <stdio.h>
#include "soc_C6748.h"
#include "lcdkC6748.h"

#define _SOC_C6748_H_


//#define EMIFA_READ_SETUP_RESETVAL (0x00)
//#define EMIFA_READ_STROBE_RESETVAL (0x00)
//#define EMIFA_READ_HOLD_RESETVAL (0x00)
//#define EMIFA_TA_RESETVAL (0x00)


int main(void)
{
printf("hello world\n");
while(1){
printf("%d\n", GPIOPinRead(SOC_GPIO_0_REGS, 0x03));
}


}

  • Assuming LCDK, HW components map to these signals.
    SW1:5 -> ARX9/MCBSP1_DX1/GPIO0[1]
    SW1:6 -> ARX10/MCBSP1_DR1/GPIO0[2]
    SW1:7 -> ARX11/MCBSP1_FSX1/GPIO0[3]
    SW1:8 -> ARX12/MCBSP1_FSR1/GPIO0[4]
    J14:3 -> EMA_D_0/GPIO4[8]

    You need to multiplex them according to:
    SPRUH79C
    TMS320C6748 DSP
    Technical Reference Manual
    10.5.10.2 Pin Multiplexing Control 1 Register (PINMUX1)
    10.5.10.10 Pin Multiplexing Control 9 Register (PINMUX9)

    StarterWare GPIO mux config are throughout the code but here are some:
    platform\lcdkC6748\gpio.c
    platform\evmC6748\gpio.c
    examples\evmC6748\gpioCardDetect.c

    Here's possible code using StarterWare rather long defines:

    #include "hw_syscfg0_C6748.h"
    
    unsigned int savePinmux = 0;
         
    savePinmux =  HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1));
    
    savePinmux &= ~(SYSCFG_PINMUX1_PINMUX1_27_24);
    savePinmux |=  (SYSCFG_PINMUX1_PINMUX1_27_24_GPIO0_1 <<
                    SYSCFG_PINMUX1_PINMUX1_27_24_SHIFT);
    
    savePinmux &= ~(SYSCFG_PINMUX1_PINMUX1_23_20);
    savePinmux |=  (SYSCFG_PINMUX1_PINMUX1_23_20_GPIO0_2 <<
                    SYSCFG_PINMUX1_PINMUX1_23_20_SHIFT);
    
    savePinmux &= ~(SYSCFG_PINMUX1_PINMUX1_19_16);
    savePinmux |=  (SYSCFG_PINMUX1_PINMUX1_19_16_GPIO0_3 <<
                    SYSCFG_PINMUX1_PINMUX1_19_16_SHIFT);
    
    savePinmux &= ~(SYSCFG_PINMUX1_PINMUX1_15_12);
    savePinmux |=  (SYSCFG_PINMUX1_PINMUX1_15_12_GPIO0_4 <<
                    SYSCFG_PINMUX1_PINMUX1_15_12_SHIFT);
    
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1)) = savePinmux;
    
    savePinmux = HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(9));
    
    savePinmux &= ~(SYSCFG_PINMUX9_PINMUX9_31_28);
    savePinmux |=  (SYSCFG_PINMUX9_PINMUX9_31_28_GPIO4_8 <<
                    SYSCFG_PINMUX9_PINMUX9_31_28_SHIFT);
    
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(9)) = savePinmux;
    
    // StarterWare GPIO use a 1 based numbering.
    GPIOPinRead(SOC_GPIO_0_REGS,  2); //GP0[1]
    GPIOPinRead(SOC_GPIO_0_REGS,  3); //GP0[2]
    GPIOPinRead(SOC_GPIO_0_REGS,  4); //GP0[3]
    GPIOPinRead(SOC_GPIO_0_REGS,  5); //GP0[4]
    GPIOPinRead(SOC_GPIO_0_REGS, 73); //GP4[8] -> 4x16+8+1
    

  • Forgot to mention that you will probably also need to
    - enable power and clock the GPIO controller, eg.
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO,
    PSC_POWERDOMAIN_ALWAYS_ON,
    PSC_MDCTL_NEXT_ENABLE);
    - configure the GPIO as an input, eg.
    GPIODirModeSet(SOC_GPIO_0_REGS, 2, GPIO_DIR_INPUT);
    GPIODirModeSet(SOC_GPIO_0_REGS, 3, GPIO_DIR_INPUT);

    GPIODirModeSet(SOC_GPIO_0_REGS, 4, GPIO_DIR_INPUT);
    GPIODirModeSet(SOC_GPIO_0_REGS, 5, GPIO_DIR_INPUT);

    GPIODirModeSet(SOC_GPIO_0_REGS, 73, GPIO_DIR_INPUT);
    Your GEL script and power on default may not require you to do such init. But will need it when you run standalone.
  • That really helped! Thank you! Could you explain how the multiplexing code works, and how I would adapt that to work for the EMA pins instead of the GPIO pins?

    Thank you so much again!

    Melissa
  • The multiplexing code is just read-modify-write of the PINMUX registers.

    savePinmux = HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1)); // Read

    savePinmux &= ~(SYSCFG_PINMUX1_PINMUX1_23_20); // Clear bit field

    // Set bit field.
    savePinmux |= (SYSCFG_PINMUX1_PINMUX1_23_20_GPIO0_2 <<
    SYSCFG_PINMUX1_PINMUX1_23_20_SHIFT);

    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1)) = savePinmux; // Write

    The read-modify-write is to preserve the existing settings of other pins. There is nothing stopping you from just writing a constant to a PINMIX registers.

    For example, the EMA pins are numerous and take up entire PINMUX registers. The function code for EMA is usually 1. For example mulitplexing for EMA_D[0] through EMA_D[7].

    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(9)) = 0x11111111; // EMA_D[0] - EMA_D[7]

    Look in the manual at other registers for othe EMA_D and EMA_A pins.

    EDIT: Correct code fragment.

  • How would we read from the EMA data pins without interfacing with something external like SDRAM, utilising the EIMFA? We would like to just hook up data wires to the EMA pins on the back of the board.
  • I am also having a bit of trouble with GPIO configurations for this DSP board relating to some of Melissa's earlier questions. Is there a way to read from multiple GPIO pins at once? I saw that there was a method in one of the C files in the StarterWare folder, however, I am having trouble getting it to work. Can my dev board only do this if it has an AM33xx SoC?
  • Joseph P,

    Since you have two other threads going, and your problem is not exactly the same as this thread, please expect responses on your other threads so this thread can stay devoted to Melissa.

    Regards,
    RandyP
  • Melissa,

    Please refer to the datasheet to find the pin muxing choices. Then you have to use code as explained well by Norman to set the EMA_D0 pin to be a GPIO instead of the EMIFA function. Your GPIO peripheral needs to be configured for that pin to be an input, and then you should be able to read the pin using your GPIOPinRead() function.

    Regards,
    RandyP
  • @Melissa Groenewold
    The EMIF_A controller can be configured to address a simple async memory device like NOR or SRAM. SDRAM and NAND are a more complicated option. Your async memory device must handle all the various signals for a memory mapped device, eg. address, data, read, write, enable, etc. In theory, most of those signals could be left unused except chip select and data lines. I think EMIF_A has 4? chip selects that map to 4 memory ranges. Then your device can be addressed directly by address. DMA is possible for fastest transfer.

    You probably might be better off using the pins as a bank of GPIO pins rather than EMIF pins. See Joseph P thread on the reasoning for using GPIO over EMIF. Using a bank of GPIOs means you could read the data lines by reading the GPIO bank input register. The advantage of GPIOs is that they are very simple and easy to configure and program. The disadvantage is that GPIOs are much much much slower than EMIF. I don' think DMA is possible with GPIOs.
  • @Joseph P
    With due respect to Randy P, I will respond to your one question here. I am rapidly seeing pattern with all these related posts, and I loathe to get involved in another thread in what appears to be a class project.

    The StarterWare code is incomplete with regard to GPIO bank operations. It has a bank write but not bank read. As you have noticed, the AM33xx gpio_v2.c code is not the one to reference. Use gpio.c as a reference. You will need to write you own bank access functions. It is pretty easy. Just look the Technical Reference Manual. To keep it simple, code it to specific bank rather than general purpose parameterized version.

    As I noted above, EMIF might be the better way to go if you need throughput. That is if you can get EMIF configured just right.