diff options
Diffstat (limited to 'board/altera/common/sevenseg.c')
| -rw-r--r-- | board/altera/common/sevenseg.c | 220 | 
1 files changed, 220 insertions, 0 deletions
| diff --git a/board/altera/common/sevenseg.c b/board/altera/common/sevenseg.c new file mode 100644 index 000000000..fecfbd388 --- /dev/null +++ b/board/altera/common/sevenseg.c @@ -0,0 +1,220 @@ +/* + * (C) Copyright 2003, Li-Pro.Net <www.li-pro.net> + * Stephan Linz <linz@li-pro.net> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * common/sevenseg.c + * + * NIOS PIO based seven segment led support functions + */ + +#include <common.h> +#include <nios-io.h> + +#ifdef	CONFIG_SEVENSEG + +#define SEVENDEG_MASK_DP	((SEVENSEG_DIGIT_DP << 8) | SEVENSEG_DIGIT_DP) + +#ifdef	SEVENSEG_WRONLY	/* emulate read access */ +#if (SEVENSEG_ACTIVE == 0) +static unsigned int sevenseg_portval = ~0; +#else +static unsigned int sevenseg_portval = 0; +#endif +#endif + +static int sevenseg_init_done = 0; + +static inline void __sevenseg_set_masked (unsigned int mask, int value) +{ +	nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE; + +#ifdef	SEVENSEG_WRONLY	/* emulate read access */ + +#if (SEVENSEG_ACTIVE == 0) +	if (value) +		sevenseg_portval &= ~mask; +	else +		sevenseg_portval |= mask; +#else +	if (value) +		sevenseg_portval |= mask; +	else +		sevenseg_portval &= ~mask; +#endif + +	piop->data = sevenseg_portval; + +#else	/* !SEVENSEG_WRONLY */ + +#if (SEVENSEG_ACTIVE == 0) +	if (value) +		piop->data &= ~mask; +	else +		piop->data |= mask; +#else +	if (value) +		piop->data |= mask; +	else +		piop->data &= ~mask; +#endif + +#endif	/* SEVENSEG_WRONLY */ +} + +static inline void __sevenseg_toggle_masked (unsigned int mask) +{ +	nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE; + +#ifdef	SEVENSEG_WRONLY	/* emulate read access */ + +	sevenseg_portval ^= mask; +	piop->data = sevenseg_portval; + +#else	/* !SEVENSEG_WRONLY */ + +	piop->data ^= mask; + +#endif	/* SEVENSEG_WRONLY */ +} + +static inline void __sevenseg_set (unsigned int value) +{ +	nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE; + +#ifdef	SEVENSEG_WRONLY	/* emulate read access */ + +#if (SEVENSEG_ACTIVE == 0) +	sevenseg_portval = (sevenseg_portval &   SEVENDEG_MASK_DP) +		         | ((~value)         & (~SEVENDEG_MASK_DP)); +#else +	sevenseg_portval = (sevenseg_portval & SEVENDEG_MASK_DP) +		         | (value); +#endif + +	piop->data = sevenseg_portval; + +#else	/* !SEVENSEG_WRONLY */ + +#if (SEVENSEG_ACTIVE == 0) +	piop->data = (piop->data &   SEVENDEG_MASK_DP) +		   | ((~value)   & (~SEVENDEG_MASK_DP)); +#else +	piop->data = (piop->data & SEVENDEG_MASK_DP) +		   | (value); +#endif + +#endif	/* SEVENSEG_WRONLY */ +} + +static inline void __sevenseg_init (void) +{ +	nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE; + +	__sevenseg_set(0); + +#ifndef	SEVENSEG_WRONLY	/* setup direction */ + +	piop->direction |= mask; + +#endif	/* SEVENSEG_WRONLY */ +} + + +void sevenseg_set(int value) +{ +	unsigned char	digits[] = { +		SEVENSEG_DIGITS_0, +		SEVENSEG_DIGITS_1, +		SEVENSEG_DIGITS_2, +		SEVENSEG_DIGITS_3, +		SEVENSEG_DIGITS_4, +		SEVENSEG_DIGITS_5, +		SEVENSEG_DIGITS_6, +		SEVENSEG_DIGITS_7, +		SEVENSEG_DIGITS_8, +		SEVENSEG_DIGITS_9, +		SEVENSEG_DIGITS_A, +		SEVENSEG_DIGITS_B, +		SEVENSEG_DIGITS_C, +		SEVENSEG_DIGITS_D, +		SEVENSEG_DIGITS_E, +		SEVENSEG_DIGITS_F +	}; + +	if (!sevenseg_init_done) { +		__sevenseg_init(); +		sevenseg_init_done++; +	} + +	switch (value & SEVENSEG_MASK_CTRL) { + +		case SEVENSEG_RAW: +			__sevenseg_set( ( +				(digits[((value & SEVENSEG_MASK_VAL) >>  4)] << 8) | +				digits[((value & SEVENSEG_MASK_VAL) & 0xf)] ) ); +			return; +			break;	/* paranoia */ + +		case SEVENSEG_OFF: +			__sevenseg_set(0); +			__sevenseg_set_masked(SEVENDEG_MASK_DP, 0); +			return; +			break;	/* paranoia */ + +		case SEVENSEG_SET_DPL: +			__sevenseg_set_masked(SEVENSEG_DIGIT_DP, 1); +			return; +			break;	/* paranoia */ + +		case SEVENSEG_SET_DPH: +			__sevenseg_set_masked((SEVENSEG_DIGIT_DP << 8), 1); +			return; +			break;	/* paranoia */ + +		case SEVENSEG_RES_DPL: +			__sevenseg_set_masked(SEVENSEG_DIGIT_DP, 0); +			return; +			break;	/* paranoia */ + +		case SEVENSEG_RES_DPH: +			__sevenseg_set_masked((SEVENSEG_DIGIT_DP << 8), 0); +			return; +			break;	/* paranoia */ + +		case SEVENSEG_TOG_DPL: +			__sevenseg_toggle_masked(SEVENSEG_DIGIT_DP); +			return; +			break;	/* paranoia */ + +		case SEVENSEG_TOG_DPH: +			__sevenseg_toggle_masked((SEVENSEG_DIGIT_DP << 8)); +			return; +			break;	/* paranoia */ + +		case SEVENSEG_LO: +		case SEVENSEG_HI: +		case SEVENSEG_STR: +		default: +			break; +	} +} + +#endif	/* CONFIG_SEVENSEG */ |