-
Notifications
You must be signed in to change notification settings - Fork 0
/
driver.java
185 lines (157 loc) · 4.72 KB
/
driver.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package atmelProject.ledDriver;
import atmelProject.lEDBlink.Port;
import icecaptools.IcecapCompileMe;
import devices.AVR.ATMega2560.ATMega2560InterruptDispatcher;
import vm.InterruptDispatcher;
import vm.InterruptHandler;
public class Driver {
public native static void enableInterrupts();
/**
* Seven segment display driver java implementation for the ATMega1280.
* Using IceCap, see www.Icelab.dk
*
* @see IceCap, www.Icelab.dk
* @author Andrei Predoiu, Thorsten Aksel Roy, Alex Patriche
*/
static Port DDRB = new Port(0x04 + 0x20);
static Port DDRK = new Port(0x107);
static Port DDRL = new Port(0x10A);
static Port PORTB = new Port(0x05 + 0x20);
static Port TCCR0B = new Port(0x25 + 0x20);
static Port TIMSK0 = new Port(0x6E);
static Port PORTK = new Port(0x108);
static Port PORTL = new Port(0x10B);
// Hex values for numbers 0-9 + empty display
static int DIGIT[] = { 0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0,
0xFE, 0xF6, 0x00 };
static int current_display = 1;
static int mask_result = 0b00000000;
public static void main(String args[]) {
disp_init();
enableInterrupts();
ATMega2560InterruptDispatcher.init();
InterruptDispatcher.registerHandler(new TimerHandler(), (byte) 24);
while (true) {
display_value(1, 3, 4, 7, 2);
}
}
public static void disp_init() {
DDRB.port |= (1 << (1));// SHCP
DDRB.port |= (1 << (2));// DS
DDRB.port |= (1 << (3));// MR
DDRK.port |= (1 << (3)); // STCP
DDRL.port |= (1 << (3));// Display A
DDRL.port |= (1 << (2));// Display B
DDRL.port |= (1 << (1));// Display C
DDRL.port |= (1 << (0));// Display D
// enable_timer();
TCCR0B.port |= (1 << (1)) | (1 << (0)); // Set the source to CLK/64
// (from prescaler).
TIMSK0.port = (1 << (0)); // Enable Timer/Counter0 overflow interrupt.
PORTB.port &= ~(1 << (3)); // Reset the shift register once
PORTB.port |= (1 << (3)); // Disable reset again so we can input
}
static int numbers[] = { 10, 10, 10, 10 };
/**
* @ingroup display
* @brief Display a value on the 7 segment display.
* @param d1
* The value of the first digit.
* @param d2
* The value of the 2nd digit.
* @param d3
* The value of the 3rd digit.
* @param d4
* The value of the 4th digit.
* @param numbers_of_decimals
* The number of decimals to be displayed.
**/
static void display_value(int d1, int d2, int d3, int d4,
int number_of_decimals) {
d1 = DIGIT[d1];
d2 = DIGIT[d2];
d3 = DIGIT[d3];
d4 = DIGIT[d4];
if (number_of_decimals == 1) {
d1 |= 1;
} else if (number_of_decimals == 2) {
d2 |= 1;
} else if (number_of_decimals == 3) {
d3 |= 1;
} else if (number_of_decimals == 4) {
d4 |= 1;
}
numbers[3] = d1;
numbers[2] = d2;
numbers[1] = d3;
numbers[0] = d4;
}
static int value_digit, i = 0, segment_mask;
private static class TimerHandler implements InterruptHandler {
public TimerHandler() {
}
@Override
@IcecapCompileMe
public void handle() {
segment_mask = 0b00000001;
value_digit = numbers[current_display];
PORTB.port &= ~(1 << (1));
// make sure SHCP is low before putting new value on DS
for (i = 0; i < 8; i++) {
// & current segment_mask with digit we want
mask_result = segment_mask & numbers[current_display];
if (mask_result != 0)
// check if the current DS value needs to be one or 0
{
PORTB.port |= (1 << (2));
} else {
PORTB.port &= ~(1 << (2));
}
// pulse SHCP to shift value at DS into the register
PORTB.port |= (1 << (1));
// make sure SHCP is low before putting new value on DS
PORTB.port &= ~(1 << (1));
// shuffle mask bit for next segment digit
}
segment_mask = segment_mask << 1;
// STCP pulse to shift bits to SSD segments
PORTK.port |= (1 << (3));
// STCP low while we input new digit bits
PORTK.port &= ~(1 << (3));
if (current_display == 0) {
PORTL.port |= (1 << (0)); // digit 0
PORTL.port &= ~(1 << (1));
PORTL.port &= ~(1 << (2));
PORTL.port &= ~(1 << (3));
current_display++;
} else if (current_display == 1) {
PORTL.port |= (1 << (1)); // digit 1
PORTL.port &= ~(1 << (0));
PORTL.port &= ~(1 << (2));
PORTL.port &= ~(1 << (3));
current_display++;
} else if (current_display == 2) {
PORTL.port |= (1 << (2)); // digit 2
PORTL.port &= ~(1 << (0));
PORTL.port &= ~(1 << (1));
PORTL.port &= ~(1 << (3));
current_display++;
} else {
PORTL.port |= (1 << (3)); // digit 3
PORTL.port &= ~(1 << (0));
PORTL.port &= ~(1 << (1));
PORTL.port &= ~(1 << (2));
current_display = 0;
}
}
@Override
public void register() {
}
@Override
public void enable() {
}
@Override
public void disable() {
}
}
}