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.

AM6442: Unintended GPIO side effects setting GPIOs from Linux & PRU

Part Number: AM6442

Tool/software:

Hello there!

We are bit puzzled by side effects that we see when setting a set of GPIOs directly and not with the GPIO kernel driver.

With these lines, we manage to write to the output GPIO and we don't see an unintended effects.

devmem2 0x000F40F4
devmem2 0x000F40F4 w 0x00050007

echo 485 >/sys/class/gpio/export
echo out >/sys/class/gpio/gpio485/direction
echo 1 >/sys/class/gpio/gpio485/value


Now, when we use Linux/C (and also directly from PRU), GPIO0_37 goes from 1 to 0 and we don't see where we are affecting it.

Attaching C example.

Can you provide some hints on what we are missing? Thanks!

#include <fcntl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>

#define GPIO0_START_ADDRESS 0x000600000
#define GPIO0_END_ADDRESS 0x0006000FF
// datasheet/spruim2h.pdf
// Page 6478
// GPIO_BANK3_[0-15]GPIO0_[48:63]
#define GPIO_60 (1 << (60 - 32))
#define GPIO_61 (1 << (61 - 32))
// #define GPMC0_WAIT0 (1 << (37 - 32))
// ../datasheet/spruim2h.pdf
// Page 6490
// Offsets:
// 38h GPIO_DIR23 Direction 2 and 3 Register
// 3Ch GPIO_OUT_DATA23 Output Data 2 and 3 Register
// 40hG PIO_SET_DATA23 Set Data 2 and 3 Register
// 44h GPIO_CLR_DATA23 Clear Data 2 and 3 Registe
// 48h GPIO_IN_DATA23 Input Data 2 and 3 Register
#define GPIO_DIR_OFFSET 0x000000038
#define GPIO_OUT_DATA_OFFSET 0x00000003C
#define GPIO_SET_DATA_OFFSET 0x000000040
#define GPIO_CLR_DATA_OFFSET 0x000000044
#define GPIO_IN_DATA_OFFSET 0x000000048

#define GPIO0_SIZE (GPIO0_END_ADDRESS - GPIO0_START_ADDRESS)

void *gpioAddress;
uint32_t *gpio_setdata_addr;
uint32_t *gpio_direction_addr;
uint32_t *gpio_cleardata_addr;
uint32_t *gpio_getdata_addr;

void gpio_get_addr() {
int fd = open("/dev/mem", O_RDWR);
gpioAddress = mmap(0, GPIO0_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
GPIO0_START_ADDRESS);
close(fd);
gpio_setdata_addr = gpioAddress + GPIO_SET_DATA_OFFSET;
gpio_direction_addr = gpioAddress + GPIO_DIR_OFFSET;
gpio_cleardata_addr = gpioAddress + GPIO_CLR_DATA_OFFSET;
gpio_getdata_addr = gpioAddress + GPIO_IN_DATA_OFFSET;
}

// Input mode
void gpio_in(uint32_t gpio) { *gpio_direction_addr |= (uint32_t)gpio; }
// Output mode
void gpio_out(uint32_t gpio) { *gpio_direction_addr &= ~((uint32_t)gpio); }
// Set gpio
void gpio_set(uint32_t gpio) { *gpio_setdata_addr |= (uint32_t)gpio; }
// Clear gpio
void gpio_clear(uint32_t gpio) { *gpio_cleardata_addr |= (uint32_t)gpio; }

void delay(unsigned long ms) { usleep(ms * 1000); }

int main() {
gpio_get_addr();
gpio_out(GPIO_61 | GPIO_60);
while (1) {
gpio_clear(GPIO_60);
gpio_clear(GPIO_61);
delay(250);
gpio_set(GPIO_60);
gpio_clear(GPIO_61);
delay(250);
gpio_clear(GPIO_60);
gpio_set(GPIO_61);
delay(250);
gpio_set(GPIO_60);
gpio_set(GPIO_61);
delay(250);
}
return 0;
}






  • Hi Nelson, 

    The subject matter expert is out of office this week. Please kindly ping this thread if you don't hear a response by next week Wednesday.

    -Daolin

  • Hi Nelson,

    Just to keep expectations clear, on the TI E2E Forums, we cannot help with custom code that has not been tested by TI.

    If I understand the problem correctly, when toggling GPIO0_60/61, you are seeing GPIO0_37 go from high to low? Please clarify if this is incorrect.

    If this GPIO0_37 isn't being used, you can disable the TX bit for the PADCONFIG register so it shouldn't output anything.

    Best Regards,

    Anshu