sevenseg.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * (C) Copyright 2003, Li-Pro.Net <www.li-pro.net>
  3. * Stephan Linz <linz@li-pro.net>
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. *
  23. * common/sevenseg.c
  24. *
  25. * NIOS PIO based seven segment led support functions
  26. */
  27. #include <common.h>
  28. #include <nios-io.h>
  29. #ifdef CONFIG_SEVENSEG
  30. #define SEVENDEG_MASK_DP ((SEVENSEG_DIGIT_DP << 8) | SEVENSEG_DIGIT_DP)
  31. #ifdef SEVENSEG_WRONLY /* emulate read access */
  32. #if (SEVENSEG_ACTIVE == 0)
  33. static unsigned int sevenseg_portval = ~0;
  34. #else
  35. static unsigned int sevenseg_portval = 0;
  36. #endif
  37. #endif
  38. static int sevenseg_init_done = 0;
  39. static inline void __sevenseg_set_masked (unsigned int mask, int value)
  40. {
  41. nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE;
  42. #ifdef SEVENSEG_WRONLY /* emulate read access */
  43. #if (SEVENSEG_ACTIVE == 0)
  44. if (value)
  45. sevenseg_portval &= ~mask;
  46. else
  47. sevenseg_portval |= mask;
  48. #else
  49. if (value)
  50. sevenseg_portval |= mask;
  51. else
  52. sevenseg_portval &= ~mask;
  53. #endif
  54. piop->data = sevenseg_portval;
  55. #else /* !SEVENSEG_WRONLY */
  56. #if (SEVENSEG_ACTIVE == 0)
  57. if (value)
  58. piop->data &= ~mask;
  59. else
  60. piop->data |= mask;
  61. #else
  62. if (value)
  63. piop->data |= mask;
  64. else
  65. piop->data &= ~mask;
  66. #endif
  67. #endif /* SEVENSEG_WRONLY */
  68. }
  69. static inline void __sevenseg_toggle_masked (unsigned int mask)
  70. {
  71. nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE;
  72. #ifdef SEVENSEG_WRONLY /* emulate read access */
  73. sevenseg_portval ^= mask;
  74. piop->data = sevenseg_portval;
  75. #else /* !SEVENSEG_WRONLY */
  76. piop->data ^= mask;
  77. #endif /* SEVENSEG_WRONLY */
  78. }
  79. static inline void __sevenseg_set (unsigned int value)
  80. {
  81. nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE;
  82. #ifdef SEVENSEG_WRONLY /* emulate read access */
  83. #if (SEVENSEG_ACTIVE == 0)
  84. sevenseg_portval = (sevenseg_portval & SEVENDEG_MASK_DP)
  85. | ((~value) & (~SEVENDEG_MASK_DP));
  86. #else
  87. sevenseg_portval = (sevenseg_portval & SEVENDEG_MASK_DP)
  88. | (value);
  89. #endif
  90. piop->data = sevenseg_portval;
  91. #else /* !SEVENSEG_WRONLY */
  92. #if (SEVENSEG_ACTIVE == 0)
  93. piop->data = (piop->data & SEVENDEG_MASK_DP)
  94. | ((~value) & (~SEVENDEG_MASK_DP));
  95. #else
  96. piop->data = (piop->data & SEVENDEG_MASK_DP)
  97. | (value);
  98. #endif
  99. #endif /* SEVENSEG_WRONLY */
  100. }
  101. static inline void __sevenseg_init (void)
  102. {
  103. nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE;
  104. __sevenseg_set(0);
  105. #ifndef SEVENSEG_WRONLY /* setup direction */
  106. piop->direction |= mask;
  107. #endif /* SEVENSEG_WRONLY */
  108. }
  109. void sevenseg_set(int value)
  110. {
  111. unsigned char digits[] = {
  112. SEVENSEG_DIGITS_0,
  113. SEVENSEG_DIGITS_1,
  114. SEVENSEG_DIGITS_2,
  115. SEVENSEG_DIGITS_3,
  116. SEVENSEG_DIGITS_4,
  117. SEVENSEG_DIGITS_5,
  118. SEVENSEG_DIGITS_6,
  119. SEVENSEG_DIGITS_7,
  120. SEVENSEG_DIGITS_8,
  121. SEVENSEG_DIGITS_9,
  122. SEVENSEG_DIGITS_A,
  123. SEVENSEG_DIGITS_B,
  124. SEVENSEG_DIGITS_C,
  125. SEVENSEG_DIGITS_D,
  126. SEVENSEG_DIGITS_E,
  127. SEVENSEG_DIGITS_F
  128. };
  129. if (!sevenseg_init_done) {
  130. __sevenseg_init();
  131. sevenseg_init_done++;
  132. }
  133. switch (value & SEVENSEG_MASK_CTRL) {
  134. case SEVENSEG_RAW:
  135. __sevenseg_set( (
  136. (digits[((value & SEVENSEG_MASK_VAL) >> 4)] << 8) |
  137. digits[((value & SEVENSEG_MASK_VAL) & 0xf)] ) );
  138. return;
  139. break; /* paranoia */
  140. case SEVENSEG_OFF:
  141. __sevenseg_set(0);
  142. __sevenseg_set_masked(SEVENDEG_MASK_DP, 0);
  143. return;
  144. break; /* paranoia */
  145. case SEVENSEG_SET_DPL:
  146. __sevenseg_set_masked(SEVENSEG_DIGIT_DP, 1);
  147. return;
  148. break; /* paranoia */
  149. case SEVENSEG_SET_DPH:
  150. __sevenseg_set_masked((SEVENSEG_DIGIT_DP << 8), 1);
  151. return;
  152. break; /* paranoia */
  153. case SEVENSEG_RES_DPL:
  154. __sevenseg_set_masked(SEVENSEG_DIGIT_DP, 0);
  155. return;
  156. break; /* paranoia */
  157. case SEVENSEG_RES_DPH:
  158. __sevenseg_set_masked((SEVENSEG_DIGIT_DP << 8), 0);
  159. return;
  160. break; /* paranoia */
  161. case SEVENSEG_TOG_DPL:
  162. __sevenseg_toggle_masked(SEVENSEG_DIGIT_DP);
  163. return;
  164. break; /* paranoia */
  165. case SEVENSEG_TOG_DPH:
  166. __sevenseg_toggle_masked((SEVENSEG_DIGIT_DP << 8));
  167. return;
  168. break; /* paranoia */
  169. case SEVENSEG_LO:
  170. case SEVENSEG_HI:
  171. case SEVENSEG_STR:
  172. default:
  173. break;
  174. }
  175. }
  176. #endif /* CONFIG_SEVENSEG */