LED/GPIO Question

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm moving from my EVK1104 to my custom PCB, and I'm having an odd LED/GPIO problem. The EVK1104 has 4 LEDs, my custom board has 3. I've copied and modified the EVK1104's led.c/h files, as well as made a custom header for my PCB. Everything else seems to be working fine, except one LED is backwards. LED2 appears to turn on when an "LED_Off(LED2)" command is issued, and the opposite for LED_On. Here's some of the relevant code:

In my custom PCB header:

/* LED Defines */
#define LED_COUNT   3

#define LED0_GPIO   AVR32_PIN_PX41
#define LED1_GPIO   AVR32_PIN_PX22
#define LED2_GPIO   AVR32_PIN_PX20

#define LED_RED					LED0
#define LED_GREEN				LED1
#define LED_ORANGE				LED2

In led.h:

/* Identifiers of LEDs to Use with LED Functions */
#define LED0  0x01
#define LED1  0x02
#define LED2  0x04

In led.c:

void LED_Off(U32 leds)
{
  // Use the LED descriptors to get the connections of a given LED to the MCU.
  tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
  volatile avr32_gpio_port_t *led_gpio_port;
  U8 led_shift;

  // Make sure only existing LEDs are specified.
  leds &= (1 << LED_COUNT) - 1;

  // Update the saved state of all LEDs with the requested changes.
  Clr_bits(LED_State, leds);

  // While there are specified LEDs left to manage...
  while (leds)
  {
    // Select the next specified LED and turn it off.
    led_shift = 1 + ctz(leds);
    led_descriptor += led_shift;
    led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
    led_gpio_port->ovrs  = led_descriptor->GPIO.PIN_MASK;
    led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
    led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
    leds >>= led_shift;
  }
}


void LED_On(U32 leds)
{
  // Use the LED descriptors to get the connections of a given LED to the MCU.
  tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1;
  volatile avr32_gpio_port_t *led_gpio_port;
  U8 led_shift;

  // Make sure only existing LEDs are specified.
  leds &= (1 << LED_COUNT) - 1;

  // Update the saved state of all LEDs with the requested changes.
  Set_bits(LED_State, leds);

  // While there are specified LEDs left to manage...
  while (leds)
  {
    // Select the next specified LED and turn it on.
    led_shift = 1 + ctz(leds);
    led_descriptor += led_shift;
    led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT];
    led_gpio_port->ovrc  = led_descriptor->GPIO.PIN_MASK;
    led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK;
    led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK;
    leds >>= led_shift;
  }
}

I haven't changed anything in led.c, and I only removed LED3 in led.h. I did change the GPIO ports that are used for the LEDs, but that should be appropriately fixed in my custom header.

Any ideas?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As a quick fix I've just started using gpio_set_pin_high and gpio_set_pin_low to control LED2_GPIO, which does the trick, so I'm pretty sure it's something in the LED code, which is somewhat more complex than I really need for this project.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe the LED itself is installed on the board backwards? ;)

Letting the smoke out since 1978

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don’t know the EVK1104, but on the STK600 all LEDs are low-active and it might be the same on the EVK1104. If you designed your PCB with LEDs between the GPIO-pins and ground then you have high-active LEDs and they’re inverted compared to the EVK1104.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Haha, pretty sure I didn't install the LED backwards, good thought though :).

I just quadruple checked the EVK1104 schematic, and they did have the LEDs set up as low active, and my schematic is high active. I'm not sure if there's a good technical reason, but I always hated low active circuits because it seems backwards to me.

I'm still a little confused though, simply because I've got two LEDs that were functioning "correctly" and one that was not, yet they're all hooked up high active. Like I said above, I've worked around the problem by getting rid of the led driver code and just using generic gpio pin control, which works perfectly fine. The end code is perhaps not quite as pretty, but it's pretty dang obvious what "gpio_set_pin_high(LED_RED)" means!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I am starting learning about AVR32, the AT32UC3L064 MCU, and looking to do basic understanding of GPIO. Your LED program is perfect.

Do you mind post your LED program.

I created my own AT32UC3L064 board, basically, a TQFP-to-PDIP adapter with a 32Khz crystal connected to XIN32 and XOUT32 pin.

I am able to play around with AVR32 Studio--no problem. But, just wanted examples to understand IO pin syntax and setup, not as easy as the ATMEGA 8-bit series.

Any pointer to basic GPIO tutorials for the AVR32 platform is greatly appreciated!

Thanks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The LED "program" is really just a set of helper functions that were provided in an ASF Example Project as part of the user interface. I'm not really sure I can provide much help there, as I've actually ripped those files out and decided to just go straight to controlling the GPIO pins directly. I'm also using a different chip completely, so I don't know how the GPIO pins would relate.

My best advice is to check out the ASF for any GPIO examples/tutorials, specifically for the AT32UC3L. Beyond that I'm afraid I can't provide much assistance.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One good example found at

https://www.kth.se/social/upload...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

iwoloschin wrote:
Haha, pretty sure I didn't install the LED backwards, good thought though :).

I just quadruple checked the EVK1104 schematic, and they did have the LEDs set up as low active, and my schematic is high active. I'm not sure if there's a good technical reason, but I always hated low active circuits because it seems backwards to me.


Having LEDs as active low is pretty common because in general, I/Os can sink more current than they source (when sinking current you use the NMOS transistors, as opposed to the PMOS transistors which have higher resistance). This reduces heating in the MCU.

Also active low logic is useful because you can activate it with open collector logic, allowing multiple outputs to drive the signal together without logic gates.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the info. I’ve been wondering about the reason for low-active LEDs as well.