You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/// This is the Interrupt Service Routine (ISR) for Timer1 compare match on output A. We don't worry about the interrupt on output B, since we want B to mirror A; we'll update them both here.
137
+
ISR(TIMER2_COMPA_vect)
138
+
{
139
+
//in CTC mode, timer TCINT2 automatically resets to 0 when it matches OCR2A. Depending on the next bit to output,
140
+
//we may have to alter the value in OCR2A, maybe.
141
+
//to switch between "one" waveform and "zero" waveform, we assign a value to OCR2A.
142
+
143
+
//remember, anything we set for OCR2A takes effect IMMEDIATELY, so we are working within the cycle we are setting.
144
+
//first, check to see if we're in the second half of a byte; only act on the first half of a byte
145
+
//On Arduino UNO, etc, OC2A is digital pin 11, or Port B/Pin 3
146
+
if(!(PINB & _BV(PINB3))) //if the pin is high, time to do our work setting up whether this should be a zero or one.
147
+
{
148
+
//time to switch things up, maybe. send the current bit in the current packet.
149
+
//if this is the last bit to send, queue up another packet (might be the idle packet).
150
+
switch(DCC_state)
151
+
{
152
+
/// Idle: Check if a new packet is ready. If it is, fall through to dos_send_premable. Otherwise just stick a '1' out there.
153
+
case dos_idle:
154
+
if(!current_byte_counter) //if no new packet
155
+
{
156
+
// Serial.println("X");
157
+
OCR2A = OCR2B = one_count; //just send ones if we don't know what else to do. safe bet.
158
+
break;
159
+
}
160
+
//looks like there's a new packet for us to dump on the wire!
161
+
//for debugging purposes, let's print it out
162
+
// if(current_packet[1] != 0xFF)
163
+
// {
164
+
// Serial.print("Packet: ");
165
+
// for(byte j = 0; j < current_packet_size; ++j)
166
+
// {
167
+
// Serial.print(current_packet[j],HEX);
168
+
// Serial.print(" ");
169
+
// }
170
+
// Serial.println("");
171
+
// }
172
+
DCC_state = dos_send_preamble; //and fall through to dos_send_preamble
173
+
/// Preamble: In the process of producing 14 '1's, counter by current_bit_counter; when complete, move to dos_send_bstart
174
+
case dos_send_preamble:
175
+
OCR2A = OCR2B = one_count;
176
+
// Serial.print("P");
177
+
if(!--current_bit_counter)
178
+
DCC_state = dos_send_bstart;
179
+
break;
180
+
/// About to send a data byte, but have to peceed the data with a '0'. Send that '0', then move to dos_send_byte
181
+
case dos_send_bstart:
182
+
OCR2A = OCR2B = zero_count;
183
+
DCC_state = dos_send_byte;
184
+
current_bit_counter = 8;
185
+
// Serial.print(" 0 ");
186
+
break;
187
+
/// Sending a data byte; current bit is tracked with current_bit_counter, and current byte with current_byte_counter
188
+
case dos_send_byte:
189
+
if(((current_packet[current_packet_size-current_byte_counter])>>(current_bit_counter-1)) & 1) //is current bit a '1'?
190
+
{
191
+
OCR2A = OCR2B = one_count;
192
+
// Serial.print("1");
193
+
}
194
+
else//or is it a '0'
195
+
{
196
+
OCR2A = OCR2B = zero_count;
197
+
// Serial.print("0");
198
+
}
199
+
if(!--current_bit_counter) //out of bits! time to either send a new byte, or end the packet
200
+
{
201
+
if(!--current_byte_counter) //if not more bytes, move to dos_end_bit
202
+
{
203
+
DCC_state = dos_end_bit;
204
+
}
205
+
else//there are more bytes…so, go back to dos_send_bstart
206
+
{
207
+
DCC_state = dos_send_bstart;
208
+
}
209
+
}
210
+
break;
211
+
/// Done with the packet. Send out a final '1', then head back to dos_idle to check for a new packet.
212
+
case dos_end_bit:
213
+
OCR2A = OCR2B = one_count;
214
+
DCC_state = dos_idle;
215
+
current_bit_counter = PREAMBLE_LENGTH; //in preparation for a premable...
0 commit comments