ReflexBall Rally
 All Data Structures Files Functions Variables Macros
LED.c
Go to the documentation of this file.
1 #include <eZ8.h> // special encore constants, macros and flash routines
2 #include <sio.h> // special encore serial i/o routines
3 #include "charset.h"
4 #include "LED.h"
5 #include "ansi.h"
6 
7 unsigned char digit = 0, column = 0, delayCounter = 0, index = 0, stringLength = 0;
8 char videoBuffer[5][6];
9 
10 volatile char runOnce, *pSecondString; // runOnce is used scroll a text only once, the pointer will point to the second string that is shown after the scroll is complete
11 char *pString; // Pointer to string in ram
12 
13 
14 void clockLed(unsigned char digit) { // Clock the specific digit
15  if (digit == 0) {
16  PEOUT &= ~(1 << 7);
17  PEOUT |= (1 << 7);
18  }
19  else if (digit == 1) {
20  PGOUT |= (1 << 7);
21  PGOUT &= ~(1 << 7);
22  }
23  else if (digit == 2) {
24  PEOUT &= ~(1 << 5);
25  PEOUT |= (1 << 5);
26  }
27  else if (digit == 3) {
28  PEOUT &= ~(1 << 6);
29  PEOUT |= (1 << 6);
30  }
31 }
32 
33 unsigned char convertChar(char input) { // Convert to some of our own characters
34  unsigned char c;
35  if (input == 'æ' c = '~' + 1; else if (input == 'ø') c = '~' + 2; else if (input == 'å') c = '~' + 3; else if (input == 'Æ') c = '~' + 4; else if (input == 'Ø') c = '~' + 5; else if (input == 'Å') c = '~' + 6; else if (input == 'µ') c = '~' + 7; else if (input == '§') // Smiley c = '~' + 8; else if (input == '£') // <3 c = '~' + 9; else c = input; return c; } void LEDsetString(char *string) { // Set string to show on the display unsigned char i, j; DI(); // Disbable all interrupts runOnce = 0; // Reset flag stringLength = strlen(string); // Calculate length of string pString = string; // Set pointer to the start of the string for (i=0; i < 5; i++) { for (j=0;j<5;j++) videoBuffer[i][j] = character_data[convertChar(*pString)-0x20][j]; videoBuffer[i][5] = 0; pString++; if (*pString == '\0') { pString -= stringLength; break; // Break if we have reached the end of the string - this is due to the string being less than five characters wide } } for (i = stringLength; i < 4; i++) { for (j = 0; j < 5; j++) videoBuffer[i][j] = character_data[' '-0x20][j]; // Fill out the rest of the string with spaces if the string is less than five characters } digit = column = delayCounter = index = 0; // Reset all values used for multiplexing EI(); // Enable all interrupts } void LEDRunOnce(char *firstString, char* secondString) { // Used to sroll the first string once and then show the second string afterwards LEDsetString(firstString); runOnce = 1; pSecondString = secondString; // We will save the location of the second string } void moveVideoBuffer() { // Increment to the next character in the string unsigned char i, j; for (i=0; i < 5; i++) { for (j=0;j<5;j++) { if (i < 4) videoBuffer[i][j] = videoBuffer[i+1][j]; // Shift all one to the left else videoBuffer[4][j] = character_data[convertChar(*pString)-0x20][j]; // Read the next character in the string } } pString++; if (*pString == '\0') { // Check if we have reached the end of the string if (runOnce) { // This wil actually abort when it loads the last character in the 5th digit, so you have to put a space in end of the sentence runOnce = 0; LEDsetString(pSecondString); } else pString -= stringLength; // Go all the way back to the end of the string } } void LEDupdate() { // This function is called inside the interrupt PGOUT = (PGOUT & (1 << 7)) | *(&videoBuffer[0][0] + digit*6 + column + index); PEOUT |= 0x1F; // Set all cathodes high PEOUT &= ~(1 << (4-column)); // Set one cathodes low decided by column clockLed(digit); if (++digit == 4) { digit = 0; if (++column == 5) { column = 0; if (++delayCounter == SCROLL_SPEED && stringLength > 4) { // We don't have to scroll the text if there is less than five characters delayCounter = 0; if (++index > 5) { index = 0; moveVideoBuffer(); } } } } } #pragma interrupt void timer2int() { // Interrupt function LEDupdate(); } void initLED() { // Initialize Timer2 used for multiplexing of the display unsigned char i; PEDD = 0; // All output PGDD = 0; // All output PEOUT = 0x1F; // Set clocks to low and cathodes to high PGOUT = 0; // Set all low for (i=0;i<4;i++) // Turn all off by default clockLed(i); DI(); // Disable interrupt T2CTL = 0; // TEN - disable timer T2CTL |= PRE1; // PRES - Prescaler T2CTL |= (1 << 0); // TMODE - continuous mode T2H = 0; T2L = 1; T2RH = 9216 >> 8; // Interrupt every 500us T2RL = 9216 & 0xFF; SET_VECTOR(TIMER2, timer2int); // Enter the timer0int function at each interrupt // Set timer2 priority to low IRQ0ENH &= ~(1 << 7); IRQ0ENL |= (1 << 7); T2CTL |= (1 << 7); // TEN - enable timer EI(); // Enable interrupt } )
36  c = '~' + 1;
37  else if (input == 'ø' c = '~' + 2; else if (input == 'å') c = '~' + 3; else if (input == 'Æ') c = '~' + 4; else if (input == 'Ø') c = '~' + 5; else if (input == 'Å') c = '~' + 6; else if (input == 'µ') c = '~' + 7; else if (input == '§') // Smiley c = '~' + 8; else if (input == '£') // <3 c = '~' + 9; else c = input; return c; } void LEDsetString(char *string) { // Set string to show on the display unsigned char i, j; DI(); // Disbable all interrupts runOnce = 0; // Reset flag stringLength = strlen(string); // Calculate length of string pString = string; // Set pointer to the start of the string for (i=0; i < 5; i++) { for (j=0;j<5;j++) videoBuffer[i][j] = character_data[convertChar(*pString)-0x20][j]; videoBuffer[i][5] = 0; pString++; if (*pString == '\0') { pString -= stringLength; break; // Break if we have reached the end of the string - this is due to the string being less than five characters wide } } for (i = stringLength; i < 4; i++) { for (j = 0; j < 5; j++) videoBuffer[i][j] = character_data[' '-0x20][j]; // Fill out the rest of the string with spaces if the string is less than five characters } digit = column = delayCounter = index = 0; // Reset all values used for multiplexing EI(); // Enable all interrupts } void LEDRunOnce(char *firstString, char* secondString) { // Used to sroll the first string once and then show the second string afterwards LEDsetString(firstString); runOnce = 1; pSecondString = secondString; // We will save the location of the second string } void moveVideoBuffer() { // Increment to the next character in the string unsigned char i, j; for (i=0; i < 5; i++) { for (j=0;j<5;j++) { if (i < 4) videoBuffer[i][j] = videoBuffer[i+1][j]; // Shift all one to the left else videoBuffer[4][j] = character_data[convertChar(*pString)-0x20][j]; // Read the next character in the string } } pString++; if (*pString == '\0') { // Check if we have reached the end of the string if (runOnce) { // This wil actually abort when it loads the last character in the 5th digit, so you have to put a space in end of the sentence runOnce = 0; LEDsetString(pSecondString); } else pString -= stringLength; // Go all the way back to the end of the string } } void LEDupdate() { // This function is called inside the interrupt PGOUT = (PGOUT & (1 << 7)) | *(&videoBuffer[0][0] + digit*6 + column + index); PEOUT |= 0x1F; // Set all cathodes high PEOUT &= ~(1 << (4-column)); // Set one cathodes low decided by column clockLed(digit); if (++digit == 4) { digit = 0; if (++column == 5) { column = 0; if (++delayCounter == SCROLL_SPEED && stringLength > 4) { // We don't have to scroll the text if there is less than five characters delayCounter = 0; if (++index > 5) { index = 0; moveVideoBuffer(); } } } } } #pragma interrupt void timer2int() { // Interrupt function LEDupdate(); } void initLED() { // Initialize Timer2 used for multiplexing of the display unsigned char i; PEDD = 0; // All output PGDD = 0; // All output PEOUT = 0x1F; // Set clocks to low and cathodes to high PGOUT = 0; // Set all low for (i=0;i<4;i++) // Turn all off by default clockLed(i); DI(); // Disable interrupt T2CTL = 0; // TEN - disable timer T2CTL |= PRE1; // PRES - Prescaler T2CTL |= (1 << 0); // TMODE - continuous mode T2H = 0; T2L = 1; T2RH = 9216 >> 8; // Interrupt every 500us T2RL = 9216 & 0xFF; SET_VECTOR(TIMER2, timer2int); // Enter the timer0int function at each interrupt // Set timer2 priority to low IRQ0ENH &= ~(1 << 7); IRQ0ENL |= (1 << 7); T2CTL |= (1 << 7); // TEN - enable timer EI(); // Enable interrupt } )
38  c = '~' + 2;
39  else if (input == 'å' c = '~' + 3; else if (input == 'Æ') c = '~' + 4; else if (input == 'Ø') c = '~' + 5; else if (input == 'Å') c = '~' + 6; else if (input == 'µ') c = '~' + 7; else if (input == '§') // Smiley c = '~' + 8; else if (input == '£') // <3 c = '~' + 9; else c = input; return c; } void LEDsetString(char *string) { // Set string to show on the display unsigned char i, j; DI(); // Disbable all interrupts runOnce = 0; // Reset flag stringLength = strlen(string); // Calculate length of string pString = string; // Set pointer to the start of the string for (i=0; i < 5; i++) { for (j=0;j<5;j++) videoBuffer[i][j] = character_data[convertChar(*pString)-0x20][j]; videoBuffer[i][5] = 0; pString++; if (*pString == '\0') { pString -= stringLength; break; // Break if we have reached the end of the string - this is due to the string being less than five characters wide } } for (i = stringLength; i < 4; i++) { for (j = 0; j < 5; j++) videoBuffer[i][j] = character_data[' '-0x20][j]; // Fill out the rest of the string with spaces if the string is less than five characters } digit = column = delayCounter = index = 0; // Reset all values used for multiplexing EI(); // Enable all interrupts } void LEDRunOnce(char *firstString, char* secondString) { // Used to sroll the first string once and then show the second string afterwards LEDsetString(firstString); runOnce = 1; pSecondString = secondString; // We will save the location of the second string } void moveVideoBuffer() { // Increment to the next character in the string unsigned char i, j; for (i=0; i < 5; i++) { for (j=0;j<5;j++) { if (i < 4) videoBuffer[i][j] = videoBuffer[i+1][j]; // Shift all one to the left else videoBuffer[4][j] = character_data[convertChar(*pString)-0x20][j]; // Read the next character in the string } } pString++; if (*pString == '\0') { // Check if we have reached the end of the string if (runOnce) { // This wil actually abort when it loads the last character in the 5th digit, so you have to put a space in end of the sentence runOnce = 0; LEDsetString(pSecondString); } else pString -= stringLength; // Go all the way back to the end of the string } } void LEDupdate() { // This function is called inside the interrupt PGOUT = (PGOUT & (1 << 7)) | *(&videoBuffer[0][0] + digit*6 + column + index); PEOUT |= 0x1F; // Set all cathodes high PEOUT &= ~(1 << (4-column)); // Set one cathodes low decided by column clockLed(digit); if (++digit == 4) { digit = 0; if (++column == 5) { column = 0; if (++delayCounter == SCROLL_SPEED && stringLength > 4) { // We don't have to scroll the text if there is less than five characters delayCounter = 0; if (++index > 5) { index = 0; moveVideoBuffer(); } } } } } #pragma interrupt void timer2int() { // Interrupt function LEDupdate(); } void initLED() { // Initialize Timer2 used for multiplexing of the display unsigned char i; PEDD = 0; // All output PGDD = 0; // All output PEOUT = 0x1F; // Set clocks to low and cathodes to high PGOUT = 0; // Set all low for (i=0;i<4;i++) // Turn all off by default clockLed(i); DI(); // Disable interrupt T2CTL = 0; // TEN - disable timer T2CTL |= PRE1; // PRES - Prescaler T2CTL |= (1 << 0); // TMODE - continuous mode T2H = 0; T2L = 1; T2RH = 9216 >> 8; // Interrupt every 500us T2RL = 9216 & 0xFF; SET_VECTOR(TIMER2, timer2int); // Enter the timer0int function at each interrupt // Set timer2 priority to low IRQ0ENH &= ~(1 << 7); IRQ0ENL |= (1 << 7); T2CTL |= (1 << 7); // TEN - enable timer EI(); // Enable interrupt } )
40  c = '~' + 3;
41  else if (input == 'Æ')
42  c = '~' + 4;
43  else if (input == 'Ø')
44  c = '~' + 5;
45  else if (input == 'Å')
46  c = '~' + 6;
47  else if (input == 'µ')
48  c = '~' + 7;
49  else if (input == '§') // Smiley
50  c = '~' + 8;
51  else if (input == '£') // <3
52  c = '~' + 9;
53  else
54  c = input;
55 
56  return c;
57 }
58 
59 void LEDsetString(char *string) { // Set string to show on the display
60  unsigned char i, j;
61 
62  DI(); // Disbable all interrupts
63 
64  runOnce = 0; // Reset flag
65  stringLength = strlen(string); // Calculate length of string
66  pString = string; // Set pointer to the start of the string
67 
68  for (i=0; i < 5; i++) {
69  for (j=0;j<5;j++)
70  videoBuffer[i][j] = character_data[convertChar(*pString)-0x20][j];
71  videoBuffer[i][5] = 0;
72 
73  pString++;
74  if (*pString == '\0') {
76  break; // Break if we have reached the end of the string - this is due to the string being less than five characters wide
77  }
78  }
79  for (i = stringLength; i < 4; i++) {
80  for (j = 0; j < 5; j++)
81  videoBuffer[i][j] = character_data[' '-0x20][j]; // Fill out the rest of the string with spaces if the string is less than five characters
82  }
83 
84  digit = column = delayCounter = index = 0; // Reset all values used for multiplexing
85 
86  EI(); // Enable all interrupts
87 }
88 
89 void LEDRunOnce(char *firstString, char* secondString) { // Used to sroll the first string once and then show the second string afterwards
90  LEDsetString(firstString);
91  runOnce = 1;
92  pSecondString = secondString; // We will save the location of the second string
93 }
94 
95 void moveVideoBuffer() { // Increment to the next character in the string
96  unsigned char i, j;
97 
98  for (i=0; i < 5; i++) {
99  for (j=0;j<5;j++) {
100  if (i < 4)
101  videoBuffer[i][j] = videoBuffer[i+1][j]; // Shift all one to the left
102  else
103  videoBuffer[4][j] = character_data[convertChar(*pString)-0x20][j]; // Read the next character in the string
104  }
105  }
106  pString++;
107  if (*pString == '\0') { // Check if we have reached the end of the string
108  if (runOnce) { // This wil actually abort when it loads the last character in the 5th digit, so you have to put a space in end of the sentence
109  runOnce = 0;
111  } else
112  pString -= stringLength; // Go all the way back to the end of the string
113  }
114 }
115 
116 void LEDupdate() { // This function is called inside the interrupt
117  PGOUT = (PGOUT & (1 << 7)) | *(&videoBuffer[0][0] + digit*6 + column + index);
118  PEOUT |= 0x1F; // Set all cathodes high
119  PEOUT &= ~(1 << (4-column)); // Set one cathodes low decided by column
120 
121  clockLed(digit);
122  if (++digit == 4) {
123  digit = 0;
124  if (++column == 5) {
125  column = 0;
126  if (++delayCounter == SCROLL_SPEED && stringLength > 4) { // We don't have to scroll the text if there is less than five characters
127  delayCounter = 0;
128  if (++index > 5) {
129  index = 0;
130  moveVideoBuffer();
131  }
132  }
133  }
134  }
135 }
136 
137 #pragma interrupt
138 void timer2int() { // Interrupt function
139  LEDupdate();
140 }
141 
142 void initLED() { // Initialize Timer2 used for multiplexing of the display
143  unsigned char i;
144  PEDD = 0; // All output
145  PGDD = 0; // All output
146  PEOUT = 0x1F; // Set clocks to low and cathodes to high
147  PGOUT = 0; // Set all low
148 
149  for (i=0;i<4;i++) // Turn all off by default
150  clockLed(i);
151 
152  DI(); // Disable interrupt
153 
154  T2CTL = 0; // TEN - disable timer
155  T2CTL |= PRE1; // PRES - Prescaler
156  T2CTL |= (1 << 0); // TMODE - continuous mode
157 
158  T2H = 0;
159  T2L = 1;
160 
161  T2RH = 9216 >> 8; // Interrupt every 500us
162  T2RL = 9216 & 0xFF;
163 
164  SET_VECTOR(TIMER2, timer2int); // Enter the timer0int function at each interrupt
165 
166  // Set timer2 priority to low
167  IRQ0ENH &= ~(1 << 7);
168  IRQ0ENL |= (1 << 7);
169 
170  T2CTL |= (1 << 7); // TEN - enable timer
171 
172  EI(); // Enable interrupt
173 }