The Acme Systems shipping office will be closed for holidays from 14 august to 22 august
PLEASE NOTE: This article is obsolete or related to a discontinued product.

Using GPIO and FOXBONE syscalls

Syscalls are used to allow userspace apps to access kernel functions. FS and Net access use this for example. With the Phrozen SDK patch new syscalls for GPIO and VHDL were introduced

Using GPIO syscalls

After installing a patched SDK you will have a folder apps/gpio_test. It contains the following application, which toggles PA0, PB7, PG8 and PG24 from 0 to 1 and back. It also reads back in the state of PG2. This is not done using the GPIO driver, but a using direct syscall access. This is much faster.
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "sys/ioctl.h"
#include "fcntl.h"
#include "time.h"
#include "string.h"
#include "linux/gpio_syscalls.h"

int main(int argc, char **argv) {

	// set PA0 as output
	gpiosetdir(PORTA, DIROUT, PA0);

	// set PB7 as output
	gpiosetdir(PORTB, DIROUT, PB7);

	// set IOG24 as output
	gpiosetdir(PORTG, DIROUT, PG24);

	// set IOG8-15 as output
	gpiosetdir(PORTG, DIROUT, PG8_15);

	while(1) {
		gpiosetbits(PORTA, PA0);
		gpiosetbits(PORTB, PB7);
		gpiotogglebit(PORTG, PG24);
		gpiosetbits(PORTG, PG8);
		printf("%d\n", (gpiogetbits(PORTG, PG2))?(1):(0));
		sleep(1);

		gpioclearbits(PORTA, PA0);
		gpioclearbits(PORTB, PB7);
		gpiotogglebit(PORTG, PG24);
		gpioclearbits(PORTG, PG8);
		printf("%d\n", (gpiogetbits(PORTG, PG2))?(1):(0));

		sleep(1);
	}
	return(0);
}

In order to use the syscalls in your custom app you will need to include #include which makes the following functions and defines available :

// port defines
#define PORTA   'A'
#define PORTB   'B'
#define PORTG   'G'

//direction defines
#define DIRIN   'I'
#define DIROUT  'O'

// pin defines for PORTG
#define PG0     (1<<0)
#define PG1     (1<<1)
#define PG2     (1<<2)
#define PG3     (1<<3)
#define PG4     (1<<4)
#define PG5     (1<<5)
#define PG6     (1<<6)
#define PG7     (1<<7)
#define PG8     (1<<8)
#define PG9     (1<<9)
#define PG10    (1<<10)
#define PG11    (1<<11)
#define PG12    (1<<12)
#define PG13    (1<<13)
#define PG14    (1<<14)
#define PG15    (1<<15)
#define PG16    (1<<16)
#define PG17    (1<<17)
#define PG18    (1<<18)
#define PG19    (1<<19)
#define PG20    (1<<20)
#define PG21    (1<<21)
#define PG22    (1<<22)
#define PG23    (1<<23)
#define PG24    (1<<24)

#define PG8_15  0x00ff00
#define PG16_23 0xff0000


// pin defines for PORTA
#define PA0     (1<<0)
#define PA1     (1<<1)
#define PA2     (1<<2)
#define PA3     (1<<3)
#define PA4     (1<<4)
#define PA5     (1<<5)
#define PA6     (1<<6)
#define PA7     (1<<7)

// pin defines for PORTB
#define PB0     (1<<0)
#define PB1     (1<<1)
#define PB2     (1<<2)
#define PB3     (1<<3)
#define PB4     (1<<4)
#define PB5     (1<<5)
#define PB6     (1<<6)
#define PB7     (1<<7)

void gpiosetbits(unsigned char port, unsigned int bits);
void gpioclearbits(unsigned char port, unsigned int bits);
void gpiosetdir(unsigned char port, unsigned char dir, unsigned int bits);
void gpiotogglebit(unsigned char port, unsigned int bits);
unsigned int gpiogetbits(unsigned char port, unsigned int bits);

Using FOXBONE syscalls

After installing a patched SDK you will have a folder apps/vhdl_test. It contains the following application, which writes and reads some foxbone registers. This is much faster than using the /dev/foxbone driver.
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "sys/ioctl.h"
#include "fcntl.h"
#include "time.h"
#include "string.h"
#include 

int main(int argc, char **argv) {
        printf("%d\n", foxboneread(0x04));
        foxbonewrite(0x13, 0x0);
        foxbonewrite(0x13, 0x111);
        printf("%d\n", foxboneread(0x13));
        unsigned short int buffer[16];
        foxbonebulkread(0x13, buffer, 16);
        unsigned int i = 0;
        for(i = 0; i < 16; i++){
                printf(" -> %d\n", buffer[i]);
        };
        for(i = 0; i < 16; i++){
                buffer[i] = i%2;
        };
        foxbonewrite(0x13, 0x0);
        foxbonebulkwrite(0x13, buffer, 16);


        return(0);
} // end main()