1717#include <tiam1808/gpio.h>
1818#include <tiam1808/psc.h>
1919
20+ #include "../rproc/rproc.h"
21+ #include "../rproc/rproc_ev3.h"
22+
2023static uint32_t get_pin_index (const pbdrv_gpio_t * gpio ) {
2124 // TI API indexes pins from 1 to 144, so need to add 1.
2225 pbdrv_gpio_ev3_mux_t * mux_info = gpio -> bank ;
@@ -31,13 +34,32 @@ static void pbdrv_gpio_alt_gpio(const pbdrv_gpio_t *gpio) {
3134 pbdrv_gpio_alt (gpio , mux_info -> gpio_mode );
3235}
3336
37+ // If the pin is not in banks 0/1, the PRU is not involved.
38+ // Otherwise, if the PRU is initialized, do direction changes
39+ // via the PRU in order to prevent race conditions.
40+ // If the PRU is not initialized (i.e. doing direction changes
41+ // during early boot), also set the direction directly via
42+ // the ARM. The PRU code polls these direction change registers
43+ // continuously and is not expected to block for too long,
44+ // only on the order of microseconds.
45+ #define PBDRV_GPIO_EV3_ARM_OWNS_GPIO_BANK (pin_index ) \
46+ ((pin_index) > 32 || !pbdrv_rproc_is_ready())
47+
3448static void gpio_write (const pbdrv_gpio_t * gpio , uint8_t value ) {
3549 if (!gpio ) {
3650 return ;
3751 }
3852 pbdrv_gpio_alt_gpio (gpio );
3953 uint32_t pin_index = get_pin_index (gpio );
40- GPIODirModeSet (SOC_GPIO_0_REGS , pin_index , GPIO_DIR_OUTPUT );
54+ if (PBDRV_GPIO_EV3_ARM_OWNS_GPIO_BANK (pin_index )) {
55+ GPIODirModeSet (SOC_GPIO_0_REGS , pin_index , GPIO_DIR_OUTPUT );
56+ } else if (GPIODirModeGet (SOC_GPIO_0_REGS , pin_index ) != GPIO_DIR_OUTPUT ) {
57+ uint32_t val = 1 << (pin_index - 1 );
58+ pbdrv_rproc_ev3_pru1_shared_ram .gpio_bank_01_dir_clr = val ;
59+ while (pbdrv_rproc_ev3_pru1_shared_ram .gpio_bank_01_dir_clr ) {
60+ // Wait for the PRU to process the command
61+ }
62+ }
4163 GPIOPinWrite (SOC_GPIO_0_REGS , pin_index , value );
4264}
4365
@@ -55,7 +77,15 @@ uint8_t pbdrv_gpio_input(const pbdrv_gpio_t *gpio) {
5577 }
5678 pbdrv_gpio_alt_gpio (gpio );
5779 uint32_t pin_index = get_pin_index (gpio );
58- GPIODirModeSet (SOC_GPIO_0_REGS , pin_index , GPIO_DIR_INPUT );
80+ if (PBDRV_GPIO_EV3_ARM_OWNS_GPIO_BANK (pin_index )) {
81+ GPIODirModeSet (SOC_GPIO_0_REGS , pin_index , GPIO_DIR_INPUT );
82+ } else if (GPIODirModeGet (SOC_GPIO_0_REGS , pin_index ) != GPIO_DIR_INPUT ) {
83+ uint32_t val = 1 << (pin_index - 1 );
84+ pbdrv_rproc_ev3_pru1_shared_ram .gpio_bank_01_dir_set = val ;
85+ while (pbdrv_rproc_ev3_pru1_shared_ram .gpio_bank_01_dir_set ) {
86+ // Wait for the PRU to process the command
87+ }
88+ }
5989 return GPIOPinRead (SOC_GPIO_0_REGS , pin_index ) == GPIO_PIN_HIGH ;
6090}
6191
0 commit comments