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.

TMS320C6748: GPIO1[15] reading input not working

Part Number: TMS320C6748

Hi,

I am trying to read GPIO1[15] input but the value is always the same. 

Other GPIO pins work fine when configured as input and GPIO configured in relevant pinmux.

Source code used to reproduce the issue:

#define HW_PINMUX2_GPIO1_MASK 0xFFFF0F00u

#define HW_PINMUX2_GPIO1_ENABLE 0x00004048u

#define GPIOPINNUMBER(bank, pin) ((bank << 4) | (pin + 1))

#define GPIO_BANK_1_NR 1
#define GPIO_1_12_PIN_NR 12
#define GPIO_1_14_PIN_NR 14
#define GPIO_1_15_PIN_NR 15

#define GPIO_1_12_PIN GPIOPINNUMBER(GPIO_BANK_1_NR, GPIO_1_12_PIN_NR)
#define GPIO_1_14_PIN GPIOPINNUMBER(GPIO_BANK_1_NR, GPIO_1_14_PIN_NR)
#define GPIO_1_15_PIN GPIOPINNUMBER(GPIO_BANK_1_NR, GPIO_1_15_PIN_NR)

uint8_t version = 0;

// Unlock kick registers (necessary on C6748)
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_KICK0R) = SYSCFG_KICK0R_UNLOCK;
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_KICK1R) = SYSCFG_KICK1R_UNLOCK;

// Configure GPIO pins to GPIO

HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(2)) &= HW_PINMUX2_GPIO1_MASK;
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(2)) |= HW_PINMUX2_GPIO1_ENABLE;

Task_sleep(1); // 1ms delay

version = GPIOPinRead(SOC_GPIO_0_REGS, GPIO_1_14_PIN);
version |= GPIOPinRead(SOC_GPIO_0_REGS, GPIO_1_15_PIN) << 1;
version |= GPIOPinRead(SOC_GPIO_0_REGS, GPIO_1_12_PIN) << 2;

Following code output shows that second bit (GPIO1[15]) of version variable is always 0.

If I do:

GPIODirModeSet(SOC_GPIO_0_REGS, GPIO_1_15_PIN, GPIO_DIR_INPUT); 

before reading the value will always be 1.

Other pins GPIO1[12] and GPIO1[14] are working fine.

GPIO1[15] is shared with McASP I/O pin AXR7.  When the pin is read from MCASP_PDIN then the value changes but it does not when read from relevant GPIO register.

When using McASP registers then the readout is correct: 

HWREG(SOC_MCASP_0_CTRL_REGS + MCASP_PFUNC) = 0xFEFF;

PDINvar = HWREG(SOC_MCASP_0_CTRL_REGS + MCASP_PDIN);

Any ideas why?

Best reagards,

Teet

  • Your code appears to be okay. Are you running a multitasking? Is there other tasks that might change the GPIO configuration? Maybe read back the config registers at the problem point.

    You should call GPIODirModeSet() before using the GPIO. In theory, at reset all GPIOs are input but I think it still best to set the direction to input.

    How are you testing the GPIO input? Are you applying a logic level to the pin? One difference between GP1[15] and GP1[12]/GP[14] is that are on two different default pullup controls. Does your design assume a pullup or pulldown.
  • Thanks for the quick response.

    I am running a multitasking application... but I have tested the same code also on singlethreaded simple application and the result is the same.

    When setting GPIO1[15] direction as input with GPIODirModeSet() it reverses the state of the pin. Other pin values are correct so I haven't set the direction for those.

    I am testing with multimeter and by pulling the pin low manually with a wire.

    I intentionally left out my code for setting the pullup/down controls. But yes, I do that as well. Just before the delay and after pinmux. Here's how:

    HWREG(SOC_SYSCFG_1_REGS + SYSCFG1_PUPD_ENA) |= SYSCFG1_PUPD_ENA_PUPDENA4; // Enable PUPD for pin group CP[4]
    HWREG(SOC_SYSCFG_1_REGS + SYSCFG1_PUPD_ENA) |= SYSCFG1_PUPD_ENA_PUPDENA5; // Enable PUPD for pin group CP[5]

    HWREG(SOC_SYSCFG_1_REGS + SYSCFG1_PUPD_SEL) &= ~SYSCFG1_PUPD_SEL_PUPDSEL4; // Internal pull-down functionality for pin group CP[4] is disabled
    HWREG(SOC_SYSCFG_1_REGS + SYSCFG1_PUPD_SEL) &= ~SYSCFG1_PUPD_SEL_PUPDSEL5; // Internal pull-down functionality for pin group CP[5] is disabled

    And I restore it to default afterward.

    I will take a look what's in the config registers when the problem occurs.

  • I have now checked the pinmux value directly before and after reading the GPIO pin value.

    The pinmux is read from:
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(2));

    and the value is always 0x04404048.

    This seems correct and corresponds to specification.

    We have a physical 1kOhm pull-up on our PCB and I am trying to pull it down with a wire to ground.

  • The pinmux does look good. Another register to check is GPIO direction. Use
    GPIODirModeGet() or the entire register
    HWREG(SOC_GPIO_0_REGS + GPIO_DIR(0))

    Have you enabled power and clock to the GPIO controller? Likely you have as the other GPIOs work.

    This macro might be problematic
    #define GPIOPINNUMBER(bank, pin) ((bank << 4) | (pin + 1))
    I think it should be
    #define GPIOPINNUMBER(bank, pin) ((bank << 4) + (pin + 1))
  • Or maybe not. This should be the correct way to convert zero-based bank/pin to one-based pin.
    #define GPIOPINNUMBER(bank, pin) (((bank << 4) | pin) + 1)
  • You have proposed the correct solution.

    Problem is that I have not written this macro myself and it is used to configure all the other GPIOs for a while now. It seems that the issue only occurs when bank number has the 1st bit high, that is for bank 1, 3, 5, 7. Fortunately we are not using any of those. I wonder if the macro is reused from some example. In that case it might cause some trouble for a more wider range of users.

    Thank you.

  • Strictly speaking the error occurs if the bank is odd and the pin is 15.

    #define GPIOPINNUMBER(bank, pin) ((bank << 4) | (pin + 1))
    0/15 -> 16 good
    1/14 -> 31 good
    1/15 -> 16 bad, should be 32
    2/14 -> 47 good
    2/15 -> 48 good

    Is macro somewhere is the StarterWare release? Or just in your code stream?
  • I looked for it in StarterWare but I didn't find it. So probably legacy from our former in house developer.