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);
}
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”
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.
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.