Debug LED (GPIO 0) on Broadcom eval board...

Hi,

I’m trying to access the GPIO pins on a Broadcom 91250A eval board. E.g. switch the Debug LED (GPIO 0) on/off. The next step will be setting a GPIO pin as external interrupt pin (driven by an external source).

So my DEBUG LED test code is as follows:

int main(int anz,char **args)
{
uintptr_t handle;
volatile uint16_t value;
if(ThreadCtl(_NTO_TCTL_IO,0) == -1) printf(“WRONG PERMISSION\n”);
handle = mmap_device_io(0x02, 0x80050020);
value= in16(handle);
printf(“This is the value: 0x%X\n”,value);
return 0;
}

The problem is the sigbus error at line “value = in16(handle);”

Is the GPIO pin adress wrong? I also tried BCM1250_INTR_GPIO_0 and 0x10061AA0 (see bcm1250 doc) instead 0x80050020.

Thanks a lot,
Christian Kummer

You program is ok, although you should check the value return my mmap for error. It must be the wrong address or the device must be enabled first.

I tried error checks, but everything seems to be okay… error number after mmap is 0 (OK). I contacted QNX support to handle this problem. I’ll post the answer asap.

error number after mmap is 0? What to you mean by that, that handle is equal to 0 or that errno is equal to 0.

the errno after calling mmap_device_io() is 0. handle is not NULL.
mmap_device_io() help: […] Returns: A handle to the device’s I/O memory, or MAP_DEVICE_FAILED if an error occurs (errno is set). […]

Just double checking. Note that if a function does not return a error code the value of errno is NOT set. That means a function that works doesn’t have to set errno to EOK.

MAP_DEVICE_FAILED is not equal to NULL but rather -1.

If anyone is interested in the solution…

The important part is:

   printf("set GPIO_DIRECTION \t= \n");
   value = setBitUint64(0, 0);
   //value = 0;
   dumpBinaryUint64(value);
   set64bit(value, GPIO_DIRECTION);
   printf(" ... DONE!\n");
   
for (i=0; i<10; i++) {
   
   printf("set GPIO_PIN_SET \t= \n");
   value = setBitUint64(0, 0);
   dumpBinaryUint64(value);
   set64bit(value, GPIO_PIN_SET);
   printf(" ... LED ON!\n");
   usleep(500000);
   
   printf("set GPIO_PIN_CLR \t= \n");
   value = setBitUint64(0, 0);
   dumpBinaryUint64(value);
   set64bit(value, GPIO_PIN_CLR);
   printf(" ... LED OFF!\n");
   usleep(500000);
} 

…there it is the whole code (for Broadcom 91250A board):

#include <stdlib.h>
#include <stdio.h>
#include <sys/neutrino.h>
#include <hw/inout.h>
#include <stdint.h>
#include <sys/mman.h>
#include <mips/bcm1250intr.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#define SYSTEM_REV			0x10020000
#define SYSTEM_CFG			0x10020008
#define SYSTEM_MANUF		0x10038000

#define IR_BASE				0x10020000
#define IR_DIAG_0 			IR_BASE + 0x0010
#define IR_DIAG_1 			IR_BASE + 0x2010
#define IR_MASK_0 			IR_BASE + 0x0028
#define IR_MASK_1 			IR_BASE + 0x2028
#define IR_SOURCE_STATUS_0 	IR_BASE + 0x0040
#define IR_SOURCE_STATUS_1 	IR_BASE + 0x2040

#define GPIO_BASE			0x10060000
#define GPIO_INPUT_INVERT	GPIO_BASE + 0x1A90
#define GPIO_READ		 	GPIO_BASE + 0x1AA0
#define GPIO_GLITCH		 	GPIO_BASE + 0x1A98
#define GPIO_DIRECTION	 	GPIO_BASE + 0x1AA8
#define GPIO_PIN_SET		GPIO_BASE + 0x1AB8
#define GPIO_PIN_CLR		GPIO_BASE + 0x1AB0

//
//
void bin_prnt_byte(int x)
{
   int n;
   for(n=0; n < 8; n++)
   {
      if((x & 0x80) !=0)
      {
         printf("1");
      }
      else
      {
         printf("0");
      }
      if (n==3)
      {
         printf(" "); /* insert a space between nibbles */
      }
      x = x<<1;
   }
}

//
//
void dumpBinaryUint64(uint64_t x)
{
   int tmp;
   int i;
   for (i=7; i>=0; i--) {
   		tmp = (x>>8*i)&0xFF;
   		bin_prnt_byte(tmp);
   		printf(" ");
   }
}

// 
//
void dumpHex(uint64_t x)
{
  unsigned char* p = (unsigned char*)&x;
  int i;
  printf( "0x");
  for( i=0; i <=7; i++)
    printf( "%02X", p[i]);
}


//
//
uint64_t get64bit(uint64_t io) {
	int errvalue;
	uintptr_t handle;
	volatile uint64_t value;
	if(ThreadCtl(_NTO_TCTL_IO,0) ==-1) printf("WRONG PERMISSION\n");
	errno = EOK;
	handle = mmap_device_io(0x08, io);
    errvalue = errno;
    if (errno != 0) {
    	printf( "Error after mmap_device_io()() in read64bit() %d\n", errvalue);
    	printf( "That means: %s\n", strerror( errvalue ) );
    	return 0;
    }
	errno = EOK;
	//in32s((uint64_t *) &value, 0x02, handle);
	//value = in32(handle);
	value = in32(handle);
	value = value<<32;
	value += in32(handle+0x4);
	errvalue = errno;
    if (errno != 0) {
    	printf( "Error after in32s() in read64bit() %d\n", errvalue);
    	printf( "That means: %s\n", strerror( errvalue ) );
    	munmap_device_io(handle, 0x08);
    	return 0;
    }
	munmap_device_io(handle, 0x08);
	printf(" 0x%16llX ", value);
	return value;
}

uint32_t get32bit(uint64_t io) {
	int errvalue;
	uintptr_t handle;
	volatile uint32_t value;
	if(ThreadCtl(_NTO_TCTL_IO,0) ==-1) printf("WRONG PERMISSION\n");
	errno = EOK;
	handle = mmap_device_io(0x04, io);
    errvalue = errno;
    if (errno != 0) {
    	printf( "Error after mmap_device_io()() in read64bit() %d\n", errvalue);
    	printf( "That means: %s\n", strerror( errvalue ) );
    	return 0;
    }
	errno = EOK;
	value = in32(handle);
	errvalue = errno;
    if (errno != 0) {
    	printf( "Error after in32s() in read64bit() %d\n", errvalue);
    	printf( "That means: %s\n", strerror( errvalue ) );
    	munmap_device_io(handle, 0x04);
    	return 0;
    }
	munmap_device_io(handle, 0x04);
	//printf(" %d ", value);
	return value;
}

//
//
int set64bit(uint64_t value ,uint64_t io) {
	int errvalue;
	uintptr_t handle;
	if(ThreadCtl(_NTO_TCTL_IO,0) ==-1) printf("WRONG PERMISSION\n");
	errno = EOK;
	handle = mmap_device_io(0x08, io);
    errvalue = errno;
    if (errno != 0) {
    	printf( "Error after mmap_device_io()() in set64bit() %d\n", errvalue);
    	printf( "That means: %s\n", strerror( errvalue ) );
    	return -1;
    }
	errno = EOK;

	out32(handle, (uint32_t) ((value & 0xFFFFFFFF00000000)>>32));
	out32(handle+0x4, (uint32_t) (value & 0x00000000FFFFFFFF));
	//printf(" 0x%X ", (uint32_t) ((value & 0xFFFFFFFF00000000)>>32));
	//printf(" 0x%X", (uint32_t) (value & 0x00000000FFFFFFFF));
	//out32s((const uint64_t *) &value, 0x02, handle);
	errvalue = errno;
    if (errno != 0) {
    	printf( "Error after in32s() in set64bit() %d\n", errvalue);
    	printf( "That means: %s\n", strerror( errvalue ) );
    	munmap_device_io(handle, 0x08);
    	return -1;
    }
	munmap_device_io(handle, 0x08);
	return 0;
}



// Set a bit in 64-bit variable
// Bit count from 63 to 0
uint64_t setBitUint64(const unsigned int bitNr, uint64_t input) {
	uint64_t tmp;
	if (bitNr > 63) return input;
	tmp=1;
	tmp = tmp<<bitNr;
	return input | tmp;
}


int main(int anz,char **args){
	uint64_t value;
	int i;

	printf("get SYSTEM_REV \t\t= ");
	value = get64bit(SYSTEM_REV);
	printf(" 0x%8X", get32bit(SYSTEM_REV));
	printf(" 0x%8X", get32bit(SYSTEM_REV+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");

	printf("get SYSTEM_MANUF \t= ");
	value = get64bit(SYSTEM_MANUF);
	printf(" 0x%8X", get32bit(SYSTEM_MANUF));
	printf(" 0x%8X", get32bit(SYSTEM_MANUF+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");

	printf("get SYSTEM_CFG \t\t= ");
	value = get64bit(SYSTEM_CFG);
	printf(" 0x%8X", get32bit(SYSTEM_CFG));
	printf(" 0x%8X", get32bit(SYSTEM_CFG+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");

/*
	// WARNING! This performs a full system reset !!!	
	printf("set SYSTEM_CFG Bit 60 (RESET!!!!) = \n");
	value = setBitUint64(60, value);
	dumpBinaryUint64(value);
	set64bit(value, SYSTEM_CFG);
	printf(" ... DONE!\n");
*/

	printf("get IR_DIAG_0 (Core0) \t= ");
	value = get64bit(IR_DIAG_0);
	printf(" 0x%8X", get32bit(IR_DIAG_0));
	printf(" 0x%8X", get32bit(IR_DIAG_0+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");
	
	printf("get IR_DIAG_1 (Core1) \t= ");
	value = get64bit(IR_DIAG_1);
	printf(" 0x%8X", get32bit(IR_DIAG_1));
	printf(" 0x%8X", get32bit(IR_DIAG_1+0x4));
	printf("\n");	
	dumpBinaryUint64(value);
	printf("\n");
	
	printf("get IR_MASK_0 (Core0) \t= ");
	value = get64bit(IR_MASK_0);
	printf(" 0x%8X", get32bit(IR_MASK_0));
	printf(" 0x%8X", get32bit(IR_MASK_0+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");
	
	printf("get IR_MASK_1 (Core1) \t= ");
	value = get64bit(IR_MASK_1);
	printf(" 0x%8X", get32bit(IR_MASK_1));
	printf(" 0x%8X", get32bit(IR_MASK_1+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");
	
	printf("set GPIO_DIRECTION \t= \n");
	value = setBitUint64(0, 0);
	//value = 0;
	dumpBinaryUint64(value);
	set64bit(value, GPIO_DIRECTION);
	printf(" ... DONE!\n");
	
for (i=0; i<10; i++) {
	
	printf("set GPIO_PIN_SET \t= \n");
	value = setBitUint64(0, 0);
	dumpBinaryUint64(value);
	set64bit(value, GPIO_PIN_SET);
	printf(" ... LED ON!\n");
	usleep(500000);
	
	printf("set GPIO_PIN_CLR \t= \n");
	value = setBitUint64(0, 0);
	dumpBinaryUint64(value);
	set64bit(value, GPIO_PIN_CLR);
	printf(" ... LED OFF!\n");
	usleep(500000);
}
	
	printf("get IR_SOURCE_STATUS_0 \t= ");
	value = get64bit(IR_SOURCE_STATUS_0);
	printf(" 0x%8X", get32bit(IR_SOURCE_STATUS_0));
	printf(" 0x%8X", get32bit(IR_SOURCE_STATUS_0+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");
	
	printf("get IR_SOURCE_STATUS_1 \t= ");
	value = get64bit(IR_SOURCE_STATUS_1);
	printf(" 0x%8X", get32bit(IR_SOURCE_STATUS_1));
	printf(" 0x%8X", get32bit(IR_SOURCE_STATUS_1+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");
	
	printf("get GPIO_INPUT_INVERT \t= ");
	value = get64bit(GPIO_INPUT_INVERT);
	printf(" 0x%8X", get32bit(GPIO_INPUT_INVERT));
	printf(" 0x%8X", get32bit(GPIO_INPUT_INVERT+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");
	
	printf("get GPIO_READ \t\t= ");
	value = get64bit(GPIO_READ);
	printf(" 0x%8X", get32bit(GPIO_READ));
	printf(" 0x%8X", get32bit(GPIO_READ+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");
	
	printf("get GPIO_DIRECTION \t= ");
	value = get64bit(GPIO_DIRECTION);
	printf(" 0x%8X", get32bit(GPIO_DIRECTION));
	printf(" 0x%8X", get32bit(GPIO_DIRECTION+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");

	printf("get GPIO_GLITCH \t= ");
	value = get64bit(GPIO_GLITCH);
	printf(" 0x%8X", get32bit(GPIO_GLITCH));
	printf(" 0x%8X", get32bit(GPIO_GLITCH+0x4));
	printf("\n");
	dumpBinaryUint64(value);
	printf("\n");
	
	
	return 0;
}

As I said :
handle = mmap_device_io(0x08, io);
errvalue = errno;
if (errno != 0) {

This is bad code, there is no guaranty that errno is equal to 0 even if mmap_device_io works. This is the kind of code that works one day and does not the other.

You are definitly right, it is bad code. This quick and dirty hack is only for testing right now. I did not care about error handling etc. anymore. The goal was to find the right adresses for the board and get the LED working. But thanks a lot anyway. I really appreciate your help.