//////////////////////////////////////// | |
// blinkR30.pru0.c | |
// Blinks LEDs wired to P9_29 (and others) by writing register R30 on the PRU | |
// Wiring: P9_29 connects to the plus lead of an LED. The negative lead of the | |
// LED goes to a 220 Ohm resistor. The other lead of the resistor goes | |
// to ground. | |
// Setup: config_pin P9_29 pruout | |
// See: prugpio.h to see which pins attach to R30 | |
// PRU: pru0 | |
//////////////////////////////////////// | |
#include <stdint.h> | |
#include <pru_cfg.h> | |
#include "resource_table_empty.h" | |
#include "prugpio.h" | |
volatile register unsigned int __R30; | |
volatile register unsigned int __R31; | |
void main(void) { | |
// Select which pins to toggle. These are all on pru1_1 | |
uint32_t gpio = P9_29; | |
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */ | |
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0; | |
while(1) { | |
__R30 |= gpio; // Set the GPIO pin to 1 | |
__delay_cycles(500000000/5); // Wait 1/2 second | |
__R30 &= ~gpio; // Clear the GPIO pin | |
__delay_cycles(500000000/5); | |
} | |
__halt(); | |
} | |
// Sets pinmux | |
#pragma DATA_SECTION(init_pins, ".init_pins") | |
#pragma RETAIN(init_pins) | |
const char init_pins[] = | |
"/sys/devices/platform/ocp/ocp:P9_29_pinmux/state\0pruout\0" \ | |
"\0\0"; |
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beagleboard/81daa29b-4795-41b4-a4b6-a7f18229639c%40googlegroups.com.
On Thu, Jan 16, 2020 at 3:39 AM Andrew P. Lentvorski <bsd...@gmail.com> wrote:
>
> I've got to be missing something obvious, but I even after several rounds of RTFM, I can't seem to figure out how to get the PRU to change the direction of a pin or, at the very least, to let it go to a tri-state value.
>
> I would go out over the L3/L4 (although that kinda smashes the whole "real-time" thing), but won't that bump into the fact that the processor needs to be in supervisor mode?
I see you got some other answers, but it might help you to qualify if you are using a chip-level GPIO or PRU-level GPIO.
As mentioned, you don't need a supervisor mode to get to the L3 bus needed to configure the GPIO or pinmux. You do need to clear the STANDBY_INIT bit in SYSCFG. Then, the PRU can poke all the SoC registers that the ARM can. Below is an example that clears this bit, but doesn't need to do so, because the PRU GPIO bits are INSIDE the PRUSS, so I'll likely remove those lines from this example in the future.
#include <stdint.h>
#include <pru_cfg.h>
#include "resource_table_empty.h"
volatile register uint32_t __R30; // 32 output gpios
volatile register uint32_t __R31; // 32 input gpios
#define CONTROL_MODULE_START ((uint32_t)0x44E10000)
#define CONF_MCASP0_FSR_OFFSET 0x9A4
uint32_t volatile * const u32_control_P9_27 = (uint32_t volatile * const)(CONTROL_MODULE_START + CONF_MCASP0_FSR_OFFSET);
#define PINMUX_PRU_OUT 0x5
#define PINMUX_PRU_IN 0x6
#define DELAY_CYCLES (50000000/2)
void main(void) {
uint32_t const led = 0x00000028; // Use pru0_pru_r30_5 and pru0_pru_r32_3 as an output
// You can now monitor P9_28 frequency as reflecting state of P9_27 pinmux
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
unsigned int ui = 0;
unsigned int ui_fast = 0;
while (1) {
*u32_control_P9_27 = PINMUX_PRU_IN; // No effect on frequency while config-pin causes expected frequency shifts
++ui;
if (((*u32_control_P9_27) & 0x07) == PINMUX_PRU_OUT) { // This verifies that I actually got the correct address of the pinmux
ui_fast = 1;
} else {
ui_fast = 0;
}
__R30 = led;
__delay_cycles(DELAY_CYCLES);
if (ui_fast != 1) {
__delay_cycles(DELAY_CYCLES);
}
__R30 = 0;
__delay_cycles(DELAY_CYCLES);
if (ui_fast != 1) {
__delay_cycles(DELAY_CYCLES);
}
}
__halt();
}
On Thursday, January 16, 2020 at 9:58:39 AM UTC-8, Jason Kridner wrote:
On Thu, Jan 16, 2020 at 3:39 AM Andrew P. Lentvorski <bsd...@gmail.com> wrote:
>
> I've got to be missing something obvious, but I even after several rounds of RTFM, I can't seem to figure out how to get the PRU to change the direction of a pin or, at the very least, to let it go to a tri-state value.
>
> I would go out over the L3/L4 (although that kinda smashes the whole "real-time" thing), but won't that bump into the fact that the processor needs to be in supervisor mode?
I see you got some other answers, but it might help you to qualify if you are using a chip-level GPIO or PRU-level GPIO.
As mentioned, you don't need a supervisor mode to get to the L3 bus needed to configure the GPIO or pinmux. You do need to clear the STANDBY_INIT bit in SYSCFG. Then, the PRU can poke all the SoC registers that the ARM can. Below is an example that clears this bit, but doesn't need to do so, because the PRU GPIO bits are INSIDE the PRUSS, so I'll likely remove those lines from this example in the future.I guess I'm still missing something because the following program doesn't work. When I try to write to *u32_control_P9_27, nothing changes. I *CAN* however read from it and config-pin can change it externally just fine. So, I got the actual *pointer address* as well as various clocks and enables correct since I can read it properly.What did I get wrong?
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beagleboard/437cd2db-6711-4dbe-ba19-0a781d0f31bd%40googlegroups.com.
In order to change direction for a pin on a GPIO-SS, it needs a write access to its OE register. The PRU can do that.