Lite5200B and onboard LEDs

I want to control the LED4 on my Lite5200B board. Freescale says:

“The LEDs have been directly connected to General I/O, so you just need
to set these pins as ‘0’/‘1’ to turn on/off leds. (E.g. LED4 pin:
IR_USB_CLK, which means IR_USB_CLK is just this pin’s one function, you
can use its other functions, like GPIO.)”

I have used the GPIO Enable Register to enable GPIO_IRDA_1 (IR_USB_CLK) for GPIO, and then access the data output value register to turn it on and off; but I’m unable to get the LED to flash (LED4 remains off). Can someone please tell me what steps I am missing? Thanks! Code is shown below… StevenK

// standard includes
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>

int main() {
int i;
unsigned long MBAR = 0xf0000000; // MBAR address
unsigned int DOVR = 0x0b10; // GPIO Data Output Values Register offset
unsigned int ENAB = 0x0b04; // GPIO Enable Register offset
unsigned long *dovr_ptr = NULL; // GPIO DOVR pointer
unsigned long *enab_ptr = NULL; // GPIO ENAB pointer

printf("blink LED4\n");

// bring the GPIO Enable Register into virtual memory
enab_ptr = (unsigned long *) mmap_device_memory(0, 4, PROT_WRITE | PROT_READ | PROT_NOCACHE, 0, MBAR + ENAB );
if(enab_ptr == MAP_FAILED) {
	printf("enab_ptr mmap_device_memory failed\n");
	exit(1);
}
*enab_ptr = (*enab_ptr | 0x30000000);

// bring the GPIO Data Output Value Register into virtual memory
dovr_ptr = (unsigned long *) mmap_device_memory(0, 4, PROT_WRITE | PROT_READ | PROT_NOCACHE, 0, MBAR + DOVR );
if(dovr_ptr == MAP_FAILED) {
	printf("dovr_ptr mmap_device_memory failed\n");
	exit(1);
}

for (i=0; i<5; i++) {
	// set the IR_USB_CLK (LED4) bit to 0
	*dovr_ptr &= 0xDFFFFFFF;
	usleep(500000);

	// set the IR_USB_CLK (LED4) bit to 1
	*dovr_ptr |= 0x20000000;
	usleep(500000);
}	

}

StevenK,

I use mmap_device_io() for doing things like this. Try that instead (use the out8() call to write the value to turn on the led).

I think (not looking at the docs right now) that mmap_device_memory is used to set up DMA transfers which isn’t what your trying to do.

Tim

Tim,

I replaced the mmap_device_memory call and args with a mmap_device_io call and args - it did not appear to make a difference. (Previously I successfully used mmap_device_memory to access the MSCAN registers.)

From the docs -
mmap_device_memory : “map a device’s physical memory into a process’s address space”
mmap_device_io : “gain access to a device’s registers”

Any other thoughts? Thanks!

StevenK

Tim,

Also, I tried the out8() [and out32() since I’m writing to a 32 bit register] to no avail. :frowning:

StevenK

StevenK,

I know I have tried using mmap_device_memory for turning on an led on my board and it never worked. I eventually had to switch to mmap_device_io (after discussing it here on this site with some other people).

Here is what my code looks like (cut and pasted from several files):


// This maps it. Note the ThreadCtl() MUST be done even if you are root

bool mapAddressSpace(unsigned long address, int size, uintptr_t *baseAddr)
{
    uint64_t addr64 = address;  /* 64 bit address in memory */

	if (ThreadCtl_r(_NTO_TCTL_IO, 0) != EOK)
	{
		printf ("mapAddressSpace() - Insufficient privilege to map IO memory\n");
		return false;
	}

    *baseAddr = mmap_device_io(size, addr64);

    if (*baseAddr == MAP_DEVICE_FAILED)
    {
		printf ("mapAddressSpace() - Error %s trying to map device memory\n", strerror(errno));
		return false;
    }
	
    return true;
}


uintptr_t ledPort;

/* QNX: Map the ZT8908 processor LED into memory */
mapAddressSpace((unsigned long)0x79, 1, &ledPort);

/* Turn on ZT8908 processor LED */
port_value = byte_in(ledPort);
port_value |= 0x04;
byte_out(ledPort, port_value);

void byte_out(int port, unsigned char bytey)
{
    port = port;
    bytey = bytey;
    out8(port, bytey);
}	

unsigned char byte_in(int port)
{
    unsigned char rc;
    rc = rc;

    rc = in8(port);
    return (rc);
}

Rather than map the whole large chunk, I’d try mapping just the 1 byte address that the led is in. Get that working similar to how I did with my LED and then map in the larger area and go back to using the offset pointers you originally had.

Tim

The choice between memory mapped access and I/O access is not one that you get to make. The board comes one way or another. Usually when using Intel processors you get I/O, but not always. Other processors only support memory mapped I/O. There are a number of potential places where you might be making a mistake. A good test is to read a port and print its value. If you are getting 0xff’s, then you probably don’t have things working yet.