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.

AM6548: How to use shift register to control GPIO

Part Number: AM6548

Hi Ti,

We want to use 74hc595 shift register to control GPIO.

We are using Linux SDK 07.01.00.18 on our customized board.

From below e2e thread, Ti expert has helped to confirm SPI master side issue.

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1041185/am6548-support-shift-register-via-spi-to-control-gpio/3852528#3852528

After that, we want to know how to use slave side to control GPIO.

Any one can help this?

Thanks.

Eric

  • Hi Eric,

    There seems to be a driver in Linux: drivers/gpio/gpio-74x164.c. None of TI chipsets have interfaced prior. I do not see them in dts.

    For your reference you can look at:

    arch/arm/boot/dts/imx7d-sdb.dts

    extended_io: gpio-expander@0 {
    compatible = "fairchild,74hc595";
    gpio-controller;
    #gpio-cells = <2>;
    reg = <0>;
    registers-number = <1>;
    spi-max-frequency = <100000>;
    };

    Best Regards,
    Keerthy

  • Hi

    Yes, I found the driver as the thread I attached.

    I also modified the dts and it has probed successfully.

    But as I told, I'm not sure if the dts need to use "fairchild,74hc595" or "linux,spidev"

    When I tried to use "fairchild,74hc595" and control GPIO as normal GPIO,

    it says gpio export, echo value and etc.

    It cannot work well.

    Eric

  • Hi

    Do you have any idea about this?

    Thanks.

    Eric

  • Eric,

    No further suggestions, this may need a debug from device tree or the drivers/gpio/gpio-74x164.c.

    Unfortunately we cannot support this one due to the lack of a reproducible environment. Kindly debug this further at your end.

    Regards

    Karthik

  • Hi

    Finally, I come out a solution for this.

    Just memo here.

    In dts, we use below setting, but not using "fairchild,74hc595".

    &main_pmx0 {
    pinctrl-names = "default";
    pinctrl-0 = <&gpio0_pins_default>;

    gpio1_pins_default: gpio1_pins_default {
    pinctrl-single,pins = <
    AM65X_IOPAD(0x01d0, PIN_OUTPUT_PULLDOWN, 7) /* (AD12) SPI1_CS0.GPIO1_20 */
    >;
    };

    myspi2_pins_default: myspi2_pins_default {
    pinctrl-single,pins = <
    AM65X_IOPAD(0x01d8, PIN_INPUT, 0) /* (AH12) SPI1_CLK */
    AM65X_IOPAD(0x01dc, PIN_INPUT, 0) /* (AE12) SPI1_D0 */
    AM65X_IOPAD(0x01e0, PIN_INPUT, 0) /* (AF12) SPI1_D1 */
    //AM65X_IOPAD(0x01d0, PIN_OUTPUT, 0) /* (AD12) SPI1_CS0 */
    >;

    &main_spi1 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&myspi2_pins_default>;
    #address-cells = <1>;
    #size-cells= <0>;
    ti,pindir-d0-out-d1-in = <1>;

    spidev@0 {
    status = "okay";
    //compatible = "fairchild,74hc595";
    compatible = "linux,spidev";
    gpio-controller;
    #gpio-cells = <2>;
    reg = <0>;
    registers-number = <2>;
    registers-default = /bits/ 8 <0xb7>;
    spi-max-frequency = <100000>;
    };
    };

    In this way, we can control gpio using spi interface.

    Below are the sample code.

    static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
    {
    int ret;
    int out_fd;
    struct spi_ioc_transfer tr = {
    .tx_buf = (unsigned long)tx,
    .rx_buf = (unsigned long)rx,
    .len = len,
    .delay_usecs = delay,
    .speed_hz = speed,
    .bits_per_word = bits,
    };

    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    if (ret < 1)
    printf("can't send spi message");
    }

    int main(int argc, char *argv[])
    {
    int ret = 0;
    int fd;

    gpio_export(GPIO_LATCH);
    gpio_dir_out(GPIO_LATCH);
    gpio_export(GPIO_CS);
    gpio_dir_out(GPIO_CS);

    CS_OFF();

    fd = open(device, O_RDWR);
    if (fd < 0)
    printf("can't open device");

    /*
    * spi mode
    */
    ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode);
    if (ret == -1)
    printf("can't set spi mode");

    /*
    * bits per word
    */
    ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    if (ret == -1)
    printf("can't set bits per word");

    /*
    * max speed hz
    */
    ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
    if (ret == -1)
    printf("can't set max speed hz");

    printf("spi mode: 0x%x\n", mode);
    printf("bits per word: %d\n", bits);
    printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);

    transfer(fd, default_tx, default_rx, 2);//sizeof(default_tx));

    LATCH_ON();

    LATCH_OFF();

    gpio_unexport(GPIO_LATCH);


    close(fd);

    return ret;
    }

    Thanks.

    Eric