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.

AM437X - LED toggle

HI,

I am trying to do LED toggle using  PRU. My assembly code is

.origin 0
.entrypoint START

// GPIO3
#define GPIO3 0x481AE000
// GPIO5
#define GPIO5 0x48322000
#define GPIO_CLEARDATAOUT 0x190
#define GPIO_SETDATAOUT 0x194
#define GPIO_OE 0x134

START:
//set ARM such that PRU can write to GPIO
LBCO r0, C4, 4, 4
CLR r0, r0, 4
SBCO r0, C4, 4, 4

//base magic number for PWM
MOV r5, 250

//r6 is period (250 << 20)
LSL r6, r5, 20
//r5 is on_period (250 << 19) for 50% duty
LSL r5, r5, 19

// Configure as GPIO OUT 

MOV r3, GPIO3 | GPIO_OE
LBBO r2, r3, 0, 4
CLR r2, 2
SBBO r2, r3, 0, 4


//writes 7 to 8 user LEDs to turn on (no external hardware necessary)
PWM_ON:
    MOV r2, 3<< 6
    MOV r3, GPIO3 | GPIO_SETDATAOUT

    SBBO r2, r3, 0, 4

    MOV r4, 0

//wait until on_period is reached before turning off
//or wait until period to turn back on again
DELAY:
    ADD r4, r4, 1
    QBEQ PWM_ON, r4, r6
    QBNE DELAY, r4, r5

//writes 7 to 8 user LEDs to turn off
PWM_OFF:
    MOV r2, 3 << 6
    MOV r3, GPIO3 | GPIO_CLEARDATAOUT
    SBBO r2, r3, 0, 4
    QBA DELAY

Could you please correct me, if anything wrong in above code.

GPIO LED PINS are

GPIO3_18

GPIO3_7

GPIO3_8

GPIO5_10

GPIO5_11

GPIO5_12

GPIO5_13

GPIO5_14

On Host(ARM) Side Linux is running.

Regards,

Yuvaraj

  • Hi Yuvaraj,

    What issue are you seeing?

    A few basic things you might check:

    - Are the pinmux setting correctly configured in the Control Module?

    - Have you enabled the PRU to access memories external to the PRU-ICSS?  (See this FAQ.)

    Also, there is now a C-compiler for the PRU available through CCSv6.  Details about the compiler and examples for using the C-compiler are available here:  http://processors.wiki.ti.com/index.php/PRU-ICSS

    Regards,

    Melissa

  • Hi Melissa,

    Sorry for late reply.

    PRU SYS  CONFIG(0x26004)configured and value is

     ICSS_PRU_SYS_CONFIG: 0x0000002a

    GPIO Pin is having default setting and configured as GPIO out.

    Note: When i power on the board 4 greeen LEDs are  keep on blinking.

    Regards,

    Yuvaraj

  • Hi,Yuvaraj

    I think I faced the same problem like you.I configure the led pins in am437x-gp-evm.dts file like that:

    leds {
    pinctrl-names = "default", "sleep";
    pinctrl-0 = <&user_leds_default>;
    pinctrl-1 = <&user_leds_sleep>;

    compatible = "gpio-leds";

    led@0 {
    label = "tl437x:green:heartbeat";
    gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>;
    linux,default-trigger = "heartbeat";
    default-state = "off";
    };

    led@1 {
    label = "tl437x:green:mmc0";
    gpios = <&gpio5 8 GPIO_ACTIVE_HIGH>;
    linux,default-trigger = "mmc0";
    default-state = "off";
    };

    led@2 {
    label = "user-led0";
    gpios = <&gpio5 10 GPIO_ACTIVE_HIGH>;
    default-state = "on";
    };

    led@3 {
    label = "user-led1";
    gpios = <&gpio5 11 GPIO_ACTIVE_HIGH>;
    default-state = "on";
    };

    led@4 {
    label = "user-led2";
    gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>;
    default-state = "on";
    };

    led@5 {
    label = "user-led3";
    gpios = <&gpio5 13 GPIO_ACTIVE_HIGH>;
    default-state = "on";
    };

    };

    and the pinmux are that:

    user_leds_default: user_leds_default {
    pinctrl-single,pins = <
    0x238 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpio5_8.gpio5_8 */
    0x23c (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpio5_9.gpio5_9 */
    0x240 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpio5_10.gpio5_10 */
    0x244 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpio5_11.gpio5_11 */
    0x248 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpio5_12.gpio5_12 */
    0x24c (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpio5_13.gpio5_13 */
    >;
    };

    user_leds_sleep: user_leds_sleep {
    pinctrl-single,pins = <
    0x238 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio5_8.gpio5_8 */
    0x23c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio5_9.gpio5_9 */
    0x240 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio5_10.gpio5_10 */
    0x244 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio5_11.gpio5_11 */
    0x248 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio5_12.gpio5_12 */
    0x24c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio5_13.gpio5_13 */
    >;
    };

    but when I try to blink the led,it don't work.And I found that when I blink the led that not configure in am437x-gp-evm.dts like below,it really can work.

    led@2 {
    label = "user-led0";
    gpios = <&gpio5 10 GPIO_ACTIVE_HIGH>;
    default-state = "on";
    };

    now I don't know why .It seems that the pru cann't control the pins that we have configure in am437x-gp-evm.dts.Do you have some suggestion about that?

    Here are my pru code.

    /*
    * main.c
    */
    #include <stdint.h>
    #include <pru_cfg.h>
    #include "resource_table_empty.h"

    /* LED port address */
    #define GPIO5_BASE_ADDR 0x48322000
    #define GPIO_OE_OFFSET 0x134
    #define GPIO_CLRDATAOUT_OFFSET 0x190
    #define GPIO_SETDATAOUT_OFFSET 0x194

    volatile register uint32_t __R30;

    volatile pruCfg CT_CFG __attribute__((cregister("PRU_CFG", near), peripheral));

    int main(void) {

    volatile uint32_t i;

    /* GPI Mode 0, GPO Mode 0 */
    CT_CFG.GPCFG0 = 0;
    CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;

    volatile unsigned int led_set_addr;
    volatile unsigned int led_modeset_addr;
    volatile unsigned int led_clr_addr;

    led_set_addr = GPIO5_BASE_ADDR + GPIO_SETDATAOUT_OFFSET;
    led_clr_addr = GPIO5_BASE_ADDR + GPIO_CLRDATAOUT_OFFSET;

    /* set led port as output IO */
    led_modeset_addr = GPIO5_BASE_ADDR + GPIO_OE_OFFSET;
    *(volatile unsigned int*)led_modeset_addr ^= 0xff00;

    while(1) {

    for (i = 0; i < 4; i++) {
    __R30 = 1<<(i + 10);
    *(volatile unsigned int*)led_set_addr |= __R30;
    __delay_cycles(100000000); // half-second delay
    *(volatile unsigned int*)led_clr_addr |= __R30;
    __delay_cycles(100000000); // half-second delay
    }
    }
    /* Halt the PRU core - shouldn't get here */
    __halt();
    }