All pastes #1392215 Raw Edit

Parallel Port RGB LED PWM Contro

public c v1 · immutable
#1392215 ·published 2009-04-14 22:24 UTC
rendered paste body
/* Sean Bradly - 2009 */#include <stdio.h>#include <stdlib.h> #include <time.h>   /* for nanosleep */#include <curses.h> /* for nonblocking getch */#include <sys/io.h> /* for ioperm and outb *//* Check with /proc/ioports to make sure this io-mapping is correct */#define LPT0 0x03bc/* Modify depending on what pins you attached LEDs to */#define RED   ( 1 << 0 )#define GREEN ( 1 << 1 )#define BLUE  ( 1 << 2 )/* Simple use toggle macros */#define ON(LED)  (lpt0_shadow |=  LED)#define OFF(LED) (lpt0_shadow &= ~LED)/* One-liner to flush local copy of port to the wire */#define OUTPUT outb(lpt0_shadow,LPT0)/* char to simulate led ' '=off or [.,oO]=on w/ brightness */ #define FAKELED(val,color) (lpt0_shadow & color)?((val>192)?'O':(val>128)?'o':(val>64)?',':'.'):' '/* keep a copy of the port status to prevent clobbering pins unintentionally */static unsigned char lpt0_shadow = 0;/* Ncurses foo */WINDOW *window;int handle_keys(unsigned char *, unsigned char *, unsigned char *, unsigned int *);int main(int argc, char *argv[]){	unsigned int finished = 0;		/* Timer values */	struct timespec tm = {0,0};	int freq=1;	/* Contains current RGB values (0..255) */	unsigned char r,g,b;	unsigned char r_ctr,g_ctr,b_ctr;	r=g=b=r_ctr=g_ctr=b_ctr=0;	/* Get permission for raw IO */	if(ioperm(LPT0,3,1))	{		fprintf(stderr,"Failed to get raw IO permissions (are you root?)\n");		exit(-1);	}	/* set all output pins to 0 */	OFF(RED); OFF(GREEN); OFF(BLUE);	OUTPUT; 	/* Initialize ncurses for nonblocking key polling w/o echo */	window = initscr();	cbreak();	noecho();	nodelay(window,1);	keypad(window,1);	/* Loop until done */	while(!finished)	{		/* configure output bits */		(r_ctr<r) ? ON(RED)   : OFF(RED);		(g_ctr<g) ? ON(GREEN) : OFF(GREEN);		(b_ctr<b) ? ON(BLUE)  : OFF(BLUE);		/* send bits to the physical pins */		OUTPUT;		/* delay (1bil nanosec/sec)/(256 duty cycle steps)/(hZ)*/		tm.tv_nsec = (long)(1000000000/(double)freq/256.0); 		nanosleep(&tm,NULL);		/* update counters */		r_ctr++; g_ctr++; b_ctr++;		/* use ncurses to check keypresses */		finished = handle_keys(&r,&g,&b,&freq);	} 	/* set all pins to 0 to clean up */	OFF(RED); OFF(GREEN); OFF(BLUE);	OUTPUT; 		/* release the port (might not be needed) */	ioperm(LPT0,3,0); 	/* cleanup nurses */	endwin();	return 0;}int handle_keys(unsigned char *r, unsigned char *g, unsigned char *b, unsigned int *freq){	char status[128];	int c;		/* Dump some status info */	snprintf(status,128,"RGB:#%02hhx%02hhx%02hhx FREQ:%dHz\n",*r,*g,*b,*freq);	mvaddstr(0,0,status);	snprintf(status,128,"(%c)(%c)(%c)",FAKELED(*r,RED),FAKELED(*g,GREEN),FAKELED(*b,BLUE));	mvaddstr(1,0,status);	/* Handle each key (backspace exits) */	if((c=getch()) != ERR)	{		switch(c)		{		case 'q': *r-=1; break;		case 'w': *r+=1; break;		case 'a': *g-=1; break;		case 's': *g+=1; break;		case 'z': *b-=1; break;		case 'x': *b+=1; break;		case KEY_UP: *freq+=1; break;		case KEY_DOWN: (*freq>1)?*freq-=1:(void)0; break;		case KEY_BACKSPACE: return 1;		}	}		return 0;}