bluebox.c 36.1 KB
Newer Older
1 2 3
/*
 * Name:	bluebox.c
 * Author:	David Griffith <dave@661.org>
4
 * Date:	November 27, 2018
5
 * License:	GNU GPL v3
6
 * Version:	1
7
 *
8
 * Fuse Settings:	L:FF H:DB E:FF
9
 *
10
 * This program implements a bluebox, DTMF dialer, redbox, greenbox, and
11 12
 * 2600 pulse dialer with PWM synthesis on an AVR microcontroller.  Currently
 * only the ATtiny85 8-pin microcontroller is supported.
13
 *
14 15 16 17
 * On powerup, the keypad is checked to see which key was held down.
 * Holding down any key from 1 to 0 and star will select the tone mode
 * corresponding to that key.  This setting is lost when the bluebox is
 * switched off.  To set the powerup mode, first hold 2600 and then press
18 19 20
 * the key for the desired tone mode.  The star and hash keys will set
 * slow (120ms) or fast (75ms) tone durations respectively for MF and DTFM
 * modes.
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
 *
 * To toggle to or from playback mode, press and hold the 2600 key for
 * two seconds.  A low-high chirp will be played when going into
 * playback mode and a high-low chirp will be played when going back
 * into normal mode.  The bluebox always powers up in normal mode.
 *
 * The bluebox tracks the last 40 keystrokes after powerup or toggle
 * from playback mode.  There are twelve memory locations - one for each
 * of the numeric keys and the star and hash keys.  To save a sequence
 * of keystrokes, enter the desired sequence, then press and hold a key
 * other than 2600 for two seconds.  A short-long chirp will be played
 * to indicate that the sequence and tone mode has been saved.  This means
 * you can have an MF sequence in one memory, a DTMF sequence in another
 * and so on.  Sequences cannot be saved when in playback mode.
 *
 * To play back a sequence, first toggle the bluebox into playback mode.
 * Then press the key for the desired memory location.  The sequence
 * will then be played back using the tone mode the bluebox was in when
 * the sequence was saved.
 *
 * To clear a memory location, first clear the keystroke buffer.  This
 * happens when the bluebox is turned on and when toggling out of playback
 * mode.  Then press and hold the key for the memory location you want
 * to clear.
 *
 * Resistor network detection values assume a network of fourteen (for
 * 13-key keypad) or seventeen (for 16-key keypad) 1K ohm
 * resistors in series, from Vdd to Vss, with a tap between each
 * resistor pair.  A single pin then samples the voltage received from
 * the resistor ladder to determine the key pressed.  To avoid ADC issues
 * when trying to read at the voltage rails, taps at Vdd and Vss are not used.
52 53 54 55 56
 *
 * For all you naysayers, this program and the hardware on which it runs
 * are perfectly legal now.  The modern commercial switching offices have
 * long ago made blueboxing and redboxing impossible on the public phone
 * networks.  You can still do it on private networks specifically
57 58
 * set up to allow for this kind of thing.  Information on this can be
 * found at http://projectmf.org/.
59
 *
60 61 62 63 64
 * This program was directly inspired by Don Froula's PicBasicPro program
 * for implementing a bluebox on a PIC12F683 8-pin microcontroller.  No code
 * was reused from that program because of the wide differences between
 * PicBasicPro and C.
 * See http://projectmf.org/bluebox.html for more information on this.
65
 *
David Griffith's avatar
David Griffith committed
66 67 68
 * Many thanks go to the denizens of #AVR on irc.freenode.net for
 * answering my questions on sine wave generation.
 *
69 70 71 72
 */

#include <stdlib.h>
#include <stdint.h>
73
#include <stdbool.h>
74 75

#include <util/delay.h>		/* for _delay_ms() */
76
#include <util/atomic.h>	/* for circular buffer stuff */
77 78 79
#include <avr/io.h>
#include <avr/interrupt.h>	/* for sei() */
#include <avr/pgmspace.h>
80
#include <avr/eeprom.h>
81 82

/*
83
 * Sine samples 8-bit resolution, range 0-255, 256 samples
84
 *
85
 * http://www.daycounter.com/Calculators/Sine-Generator-Calculator.phtml
86 87 88
 *
 */
const unsigned char sine_table[] PROGMEM = {
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
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,
0x98,0x9b,0x9e,0xa2,0xa5,0xa7,0xaa,0xad,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbe,0xc1,0xc4,
0xc6,0xc9,0xcb,0xce,0xd0,0xd3,0xd5,0xd7,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,
0xea,0xeb,0xed,0xee,0xf0,0xf1,0xf3,0xf4,
0xf5,0xf6,0xf8,0xf9,0xfa,0xfa,0xfb,0xfc,
0xfd,0xfd,0xfe,0xfe,0xfe,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfd,
0xfd,0xfc,0xfb,0xfa,0xfa,0xf9,0xf8,0xf6,
0xf5,0xf4,0xf3,0xf1,0xf0,0xee,0xed,0xeb,
0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
0xda,0xd7,0xd5,0xd3,0xd0,0xce,0xcb,0xc9,
0xc6,0xc4,0xc1,0xbe,0xbc,0xb9,0xb6,0xb3,
0xb0,0xad,0xaa,0xa7,0xa5,0xa2,0x9e,0x9b,
0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,
0x67,0x64,0x61,0x5d,0x5a,0x58,0x55,0x52,
0x4f,0x4c,0x49,0x46,0x43,0x41,0x3e,0x3b,
0x39,0x36,0x34,0x31,0x2f,0x2c,0x2a,0x28,
0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,
0x15,0x14,0x12,0x11,0x0f,0x0e,0x0c,0x0b,
0x0a,0x09,0x07,0x06,0x05,0x05,0x04,0x03,
0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x02,
0x02,0x03,0x04,0x05,0x05,0x06,0x07,0x09,
0x0a,0x0b,0x0c,0x0e,0x0f,0x11,0x12,0x14,
0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
0x25,0x28,0x2a,0x2c,0x2f,0x31,0x34,0x36,
0x39,0x3b,0x3e,0x41,0x43,0x46,0x49,0x4c,
0x4f,0x52,0x55,0x58,0x5a,0x5d,0x61,0x64,
0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
121 122 123 124 125 126 127
};

#define TRUE	1
#define FALSE	0

#define DEBOUNCE_TIME	25

128 129 130 131 132 133 134 135 136
/*
 * The tone mode is stored as the first byte of a memory chunk.
 * When eeprom is initialized as the AVR is programmed, the
 * default state of each memory address is 0xFF.  Therefore, when
 * we find a chunk beginning with 0xFF, we conclude that the
 * memory location is empty.
 *
 */
#define MODE_EMPTY	0xFF
137 138 139 140 141
#define MODE_MF		0x00
#define MODE_DTMF	0x01
#define MODE_REDBOX	0x02
#define MODE_GREENBOX	0x03
#define MODE_PULSE	0x04
142
#define MODE_MIN	MODE_MF
143
#define MODE_MAX	MODE_PULSE
144 145 146

#define SEIZE_LENGTH	1000
#define SEIZE_PAUSE	1500
147 148
#define REDBOX_PAUSE	500
#define GREENBOX_PAUSE	500
149
#define PULSE_PAUSE	500
150

151 152 153 154
#define KP_LENGTH	120

#define SINE_SAMPLES	255UL
#define TICKS_PER_CYCLE	256UL
155
#define SINE_MIDPOINT	0x80	/* After decoupling, this is 0V of the sine. */
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
#define STEP_SHIFT	6
#define SAMPLES_PER_HERTZ_TIMES_256	(SINE_SAMPLES * (TICKS_PER_CYCLE << STEP_SHIFT)) / (F_CPU / 256)
#define OVERFLOW_PER_MILLISEC (F_CPU / TICKS_PER_CYCLE / 1000)

#define TIMER0_PRESCALE_1	(1<<CS00)
#define TIMER0_PRESCALE_8	(1<<CS01)
#define TIMER0_PRESCALE_64	((1<<CS01)|(1<<CS00))
#define TIMER0_PRESCALE_256	(1<<CS02)
#define TIMER0_PRESCALE_1024	((1<<CS02)|(1<<CS00))

#define TIMER0_ON(x) \
do { \
    TCCR0A = ((1<<COM0A1)|(1<<WGM01)|(1<<WGM00)); \
    TCCR0B = (x);\
} while (0)
#define TIMER0_OFF()	TCCR0A &= ~((1<<CS02)|(1<<CS01)|(1<<CS00))

173 174 175 176 177 178 179 180 181 182 183 184
#if defined(KEYPAD_13) || defined(KEYPAD_13_REV)
#define KEYS_13
#endif

#if defined(KEYPAD_16) || defined(KEYPAD_16_REV)
#define KEYS_16
#endif

#if defined(KEYS_13) && defined(KEYS_16)
#error One and only one keypad may be selected.  Check the Makefile.
#endif

185
#define KEY_NOTHING	0
186 187 188 189 190 191 192 193 194 195 196 197 198 199
#ifdef KEYPAD_13
#define KEY_1		1
#define KEY_2		2
#define KEY_3		3
#define KEY_4		4
#define KEY_5		5
#define KEY_6		6
#define KEY_7		7
#define KEY_8		8
#define KEY_9		9
#define KEY_STAR	10
#define KEY_0		11
#define KEY_HASH	12
#define KEY_SEIZE	13
200 201 202 203
#define KEY_A		90
#define KEY_B		91
#define KEY_C		92
#define KEY_D		93
204 205 206 207 208 209 210 211 212 213 214 215 216 217
#elif KEYPAD_13_REV
#define KEY_1		3
#define KEY_2		2
#define KEY_3		1
#define KEY_4		6
#define KEY_5		5
#define KEY_6		4
#define KEY_7		9
#define KEY_8		8
#define KEY_9		7
#define KEY_STAR	12
#define KEY_0		11
#define KEY_HASH	10
#define KEY_SEIZE	13
218 219 220 221
#define KEY_A		90
#define KEY_B		91
#define KEY_C		92
#define KEY_D		93
222
#elif KEYPAD_16
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
#define KEY_1		1
#define KEY_2		2
#define KEY_3		3
#define KEY_A		4
#define KEY_4		5
#define KEY_5		6
#define KEY_6		7
#define KEY_B		8
#define KEY_7		9
#define KEY_8		10
#define KEY_9		11
#define KEY_C		12
#define KEY_STAR	13
#define KEY_0		14
#define KEY_HASH	15
#define KEY_D		16
239
#define KEY_SEIZE	90
240 241 242 243 244 245 246
#elif KEYPAD_16_REV
#define KEY_1		4
#define KEY_2		3
#define KEY_3		2
#define KEY_A		1
#define KEY_4		8
#define KEY_5		7
247
#define KEY_6		6
248 249 250 251 252 253 254 255 256
#define KEY_B		5
#define KEY_7		12
#define KEY_8		11
#define KEY_9		10
#define KEY_C		9
#define KEY_STAR	16
#define KEY_0		15
#define KEY_HASH	14
#define KEY_D		13
257
#define KEY_SEIZE	90
258
#endif	/* Keypad selection */
259

260 261
#define MULT1		0.9999			/* Adjust 697hz and 700hz */
#define MULT2		1.01			/* Adjust 770hz to 2600hz */
262

263 264 265 266 267 268 269 270
#define DTMF_COL1	1209	* MULT2
#define DTMF_COL2	1336	* MULT2
#define DTMF_COL3	1477	* MULT2
#define DTMF_COL4	1633	* MULT2
#define DTMF_ROW1	697	* MULT1
#define DTMF_ROW2	770	* MULT2
#define DTMF_ROW3	852	* MULT2
#define DTMF_ROW4	941	* MULT2
271

272 273 274 275 276 277
#define MF1		700	* MULT1
#define MF2		900	* MULT2
#define MF3		1100	* MULT2
#define MF4		1300	* MULT2
#define MF5		1500	* MULT2
#define MF6		1700	* MULT2
278

279 280
#define RB1		1700	* MULT2
#define RB2		2200	* MULT2
281

282 283 284
#define UKRB		1000	* MULT2

#define SEIZE		2600	* MULT2
285

286

287
/* Number of milliseconds to make for a long press. */
288 289
#define LONGPRESS_TIME	2000

290 291 292 293 294 295 296 297 298
#define TONE_LENGTH_FAST	75
#define TONE_LENGTH_SLOW	120

#define PULSE_DURATION		66
#define PULSE_INTERVAL		34

#define ERROR_LOW_TONE		880
#define ERROR_HIGH_TONE		1760

299
#define STARTUP_TONE		1004	/* nothing held on startup */
300 301 302 303 304 305 306 307 308 309
#define DEFAULT_WAIT_TONE	1700	/* waiting for new default mode */
#define MODE_SELECT_TONE	1400	/* setting a mode to be forgotten */

#define EEPROM_STORE_START	1700
#define EEPROM_STORE_DONE	1500

#define PLAYBACK_FLIP_LOW_TONE	1300
#define PLAYBACK_FLIP_HIGH_TONE	1700


310 311
/* Two bytes, then 12 chunks of 42 (0x2A) bytes each. */
#define EEPROM_CHUNK_SIZE			0x2A
312 313
#define EEPROM_STARTUP_TONE_MODE		0x01
#define EEPROM_STARTUP_TONE_LENGTH		0x02
314
#define EEPROM_MEM1				0x03
315 316 317 318 319 320 321 322 323 324 325
#define EEPROM_MEM2				EEPROM_MEM1 + EEPROM_CHUNK_SIZE
#define EEPROM_MEM3				EEPROM_MEM2 + EEPROM_CHUNK_SIZE
#define EEPROM_MEM4				EEPROM_MEM3 + EEPROM_CHUNK_SIZE
#define EEPROM_MEM5				EEPROM_MEM4 + EEPROM_CHUNK_SIZE
#define EEPROM_MEM6				EEPROM_MEM5 + EEPROM_CHUNK_SIZE
#define EEPROM_MEM7				EEPROM_MEM6 + EEPROM_CHUNK_SIZE
#define EEPROM_MEM8				EEPROM_MEM7 + EEPROM_CHUNK_SIZE
#define EEPROM_MEM9				EEPROM_MEM8 + EEPROM_CHUNK_SIZE
#define EEPROM_MEM10				EEPROM_MEM9 + EEPROM_CHUNK_SIZE
#define EEPROM_MEM11				EEPROM_MEM10 + EEPROM_CHUNK_SIZE
#define EEPROM_MEM12				EEPROM_MEM11 + EEPROM_CHUNK_SIZE
326

327 328
#define BUFFER_SIZE	EEPROM_CHUNK_SIZE

329 330 331 332 333
/* This is where we declare the default stored settings which are added
 * by the "eeprom" Makefile target.  I ran into problems when I used the
 * zeroth byte.  Then came across a warning from Atmel not to do that.
 * I can't remember where I found that warning.
 */
334
uint8_t ee_data[] EEMEM = {0xff, MODE_MF, TONE_LENGTH_FAST};
335

336 337
uint8_t tone_mode;
uint8_t tone_length;
338
bool  playback_mode = FALSE;
339
bool  tones_on = FALSE;
340 341 342 343 344 345 346

uint16_t tone_a_step, tone_b_step;
uint16_t tone_a_place, tone_b_place;

void  init_ports(void);
void  init_settings(void);
void  init_adc(void);
347
uint8_t getkey(void);
348
void  process_key(uint8_t, bool);
349
void  process_longpress(uint8_t);
350
void  play(uint32_t, uint32_t, uint32_t);
351
void  pulse(uint8_t);
352

353 354 355
void  sleep_ms(uint16_t ms);
void  tick(void);
static uint8_t millisec_counter = OVERFLOW_PER_MILLISEC;
356
static volatile uint8_t millisec_flag = FALSE;
357

358 359 360 361
static uint16_t	longpress_counter;
static uint8_t	longpress_on = FALSE;
static volatile uint8_t longpress_flag = FALSE;

362 363
void eeprom_store(uint8_t);
void eeprom_playback(uint8_t);
364
uint16_t key2chunk(uint8_t);
365

366 367 368 369 370 371 372 373 374 375 376 377 378 379 380

/* Ring buffer stuff */

typedef uint8_t rbuf_data_t;
typedef uint8_t rbuf_count_t;

typedef struct {
	rbuf_data_t 	buffer[BUFFER_SIZE];
	rbuf_data_t	*in;
	rbuf_data_t	*out;
	rbuf_count_t	count;
} rbuf_t;

rbuf_t	rbuf;

381 382 383 384 385 386
static inline void rbuf_init(rbuf_t* const);
static inline rbuf_count_t rbuf_getcount(rbuf_t* const);
static inline bool rbuf_isempty(rbuf_t*);
static inline void rbuf_insert(rbuf_t* const, const rbuf_data_t);
static inline rbuf_data_t rbuf_remove(rbuf_t* const);

387

388 389
int main(void)
{
390
	uint8_t key;
391
	bool	startup_set = FALSE;
392
	bool	key_valid = TRUE;
393

394 395 396
	init_ports();
	init_adc();

397 398
	rbuf_init(&rbuf);

399 400 401 402 403
	/*
	 * Start TIMER0
	 * The timer is counting from 0 to 255 -- 256 values.
	 * The prescaler is 1.  Therefore our PWM frequency is F_CPU / 256.
	 */
David Griffith's avatar
David Griffith committed
404
	TIMER0_ON(TIMER0_PRESCALE_1);
405

406
	/* Read setup bytes. */
407 408
	tone_mode   = eeprom_read_byte(( uint8_t *)EEPROM_STARTUP_TONE_MODE);
	tone_length = eeprom_read_byte(( uint8_t *)EEPROM_STARTUP_TONE_LENGTH);
409

410 411 412
	/* If our startup mode is bogus, set something sensible
	 * and make noise to let the user know something's wrong.
	 */
413 414 415
	if (tone_mode < MODE_MIN || tone_mode > MODE_MAX) {
		tone_mode = MODE_MIN;
		for (key = 0; key < 4; key++) {
416
			play(TONE_LENGTH_FAST, ERROR_LOW_TONE, 0);
417 418
			sleep_ms(66);
		}
419
	}
420
	/* Same goes if the tone length is bogus. */
421
	if ((tone_length != TONE_LENGTH_SLOW) && (tone_length != TONE_LENGTH_FAST)) {
422
		tone_length = TONE_LENGTH_FAST;
423
		for (key = 0; key < 4; key++) {
424
			play(TONE_LENGTH_FAST, ERROR_HIGH_TONE, 0);
425 426 427
			sleep_ms(66);
		}
	}
428

429
/* Startup sequence for 13-key blueboxes. */
430
#ifdef KEYS_13
431
	key = getkey();		/* What key is held on startup? */
432

433
	if (key == KEY_SEIZE) {	/* We're setting a default mode. */
434
		startup_set = TRUE;
435
		play(1000, DEFAULT_WAIT_TONE, 0);
436 437
		while (key == getkey());	/* Wait for release. */
		do {				/* Get the next keystroke. */
438 439 440
			key = getkey();
		} while (key == KEY_NOTHING);
	}
441

442
	/* We're changing modes. */
443
	switch (key) {
444
	case KEY_NOTHING:	play(1000, STARTUP_TONE, 0); break;
445 446 447
	case KEY_1:	tone_mode = MODE_MF; break;
	case KEY_2:	tone_mode = MODE_DTMF; break;
	case KEY_3:	tone_mode = MODE_REDBOX; break;
David Griffith's avatar
David Griffith committed
448
	case KEY_4:	tone_mode = MODE_GREENBOX; break;
449
	case KEY_5:	tone_mode = MODE_PULSE; break;
450 451
	case KEY_STAR:	tone_length = TONE_LENGTH_SLOW; break;
	case KEY_HASH:	tone_length = TONE_LENGTH_FAST; break;
452 453 454 455
	default:	play(500, ERROR_LOW_TONE, 0);
			sleep_ms(66);
			play(500, ERROR_LOW_TONE, 0);
			key_valid = FALSE;
456
			break;
457 458
	}

David Griffith's avatar
David Griffith committed
459 460 461 462 463
	/*
	 * If 2600 was held on startup, save the new mode as default,
	 * then chirp high-low.  Otherwise, we're simply setting a mode and
	 * not saving, so then just chirp high.
	 */
464
	if (startup_set) {
465
		play(75, EEPROM_STORE_START, 0);
466 467
		eeprom_update_byte((uint8_t *)EEPROM_STARTUP_TONE_MODE, tone_mode);
		eeprom_update_byte((uint8_t *)EEPROM_STARTUP_TONE_LENGTH, tone_length);
468
		eeprom_busy_wait();
469
		play(1000, EEPROM_STORE_DONE, 0);
470
	} else {
471 472
		if (key > KEY_NOTHING && key_valid)
			play(1000, MODE_SELECT_TONE, 0);
473 474
	}

475
	while (key == getkey());	/* Wait for release. */
476
#endif	/* KEYS_13 */
477

478 479
	/*
	 * Main Loop
480 481 482 483 484 485 486 487 488
	 *
	 * Get the next keystroke.
	 * If we're in playback mode, play the sequence corresponding to
	 *   that key.
	 * Otherwise, play the tone for that key.
	 * Then check to see if the key is being held down for saving
	 *   sequences or toggling between normal and playback modes.
	 *
	 */
489
	while (TRUE) {
490 491 492
		do {	/* Get the next keystroke. */
			key = getkey();
		} while (key == KEY_NOTHING);
493

494
		if (playback_mode)
495
			eeprom_playback(key);
496
		else
497
			process_key(key, FALSE);
498

499
		process_longpress(key);
500 501
	}
	return 0;
502
} /* int main(void) */
503

504

505 506 507
/*
 * void eeprom_store(uint8_t key)
 *
508 509
 * Unload the ring buffer into a linear buffer and then write the linear
 * buffer into EEPROM.
510 511
 *
 */
512 513
void eeprom_store(uint8_t key)
{
514 515 516
	uint8_t ee_buffer[EEPROM_CHUNK_SIZE];
	uint16_t i;

517
	play(75, EEPROM_STORE_START, 0);
518

519 520 521 522 523 524 525
	ee_buffer[0] = tone_mode;
	for (i = 1; i < EEPROM_CHUNK_SIZE; i++) {
		if (rbuf_isempty(&rbuf))
			ee_buffer[i] = 0xff;
		else
			ee_buffer[i] = rbuf_remove(&rbuf);
	}
526 527 528 529 530 531

	i = key2chunk(key);

	eeprom_update_block((uint8_t *)ee_buffer, (void *)i, EEPROM_CHUNK_SIZE);
	eeprom_busy_wait();

532
	play(1000, EEPROM_STORE_DONE, 0);
533
} /* void eeprom_store(uint8_t key) */
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551


/*
 * void eeprom_playback(uint8_t key)
 *
 * Read the EEPROM memory chunk corresponding to the specified key.
 * Set the tone mode to the one specified by the first byte of the chunk.
 * Then play back the rest of the keys until we reach the end of the
 * chunk or hit 0xFF, which indicates the end of the sequence.
 *
 */
void eeprom_playback(uint8_t key)
{
	uint8_t mem[EEPROM_CHUNK_SIZE];
	uint16_t chunk;
	uint8_t i;
	uint8_t tone_mode_temp;

552 553 554 555 556 557 558 559
	/* The 2600 key always plays 2600 in normal or playback modes. */
#ifdef KEYS_13
	if (key == KEY_SEIZE) {
		process_key(key, FALSE);
		return;
	}
#endif

560 561 562 563 564 565
	chunk = key2chunk(key);
	if ((void *)chunk == NULL) {
		play(1000, 1500, 1500);
		sleep_ms(66);
		play(1000, 1500, 1500);
		return;
566 567 568 569
	}

	eeprom_read_block((uint8_t *)mem, (void *)chunk, EEPROM_CHUNK_SIZE);

570
	/* Abort if this chunk doesn't start with a valid mode. */
571
	if (mem[0] < MODE_MIN || mem[0] > MODE_MAX)
572 573 574 575 576 577 578
		return;

	tone_mode_temp = tone_mode;
	tone_mode = mem[0];

	for (i = 1; i < EEPROM_CHUNK_SIZE; i++) {
		if (mem[i] == 0xff) break;
579
		process_key(mem[i], TRUE);
580 581
	}
	tone_mode = tone_mode_temp;
582

583
	return;
584
} /* void eeprom_playback(uint_t key) */
585

586

587 588 589 590 591 592
/*
 * uint16_t key2chunk(uint8_t key)
 *
 * Convert key to corresponding memory location.
 *
 */
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
uint16_t key2chunk(uint8_t key)
{
	switch (key) {
	case KEY_1:	return EEPROM_MEM1; break;
	case KEY_2:	return EEPROM_MEM2; break;
	case KEY_3:	return EEPROM_MEM3; break;
	case KEY_4:	return EEPROM_MEM4; break;
	case KEY_5:	return EEPROM_MEM5; break;
	case KEY_6:	return EEPROM_MEM6; break;
	case KEY_7:	return EEPROM_MEM7; break;
	case KEY_8:	return EEPROM_MEM8; break;
	case KEY_9:	return EEPROM_MEM9; break;
	case KEY_STAR:	return EEPROM_MEM10; break;
	case KEY_0:	return EEPROM_MEM11; break;
	case KEY_HASH:	return EEPROM_MEM12; break;
	default: return (uint16_t) NULL;
	}
610
} /* uint16_t key2chunk(uint8_t key) */
611 612


613
/*
614 615 616 617
 * void process_key(uint8_t key, bool pause)
 *
 * Process regular keystroke.
 * Optionally add a pause after playing tone.
618 619
 *
 */
620
void process_key(uint8_t key, bool pause)
621 622 623
{
	if (key == 0) return;

624
#ifdef KEYS_13
625
	/* The 2600 key always plays 2600, so catch it here. */
626
	if (key == KEY_SEIZE) {
627
		play(SEIZE_LENGTH, SEIZE, SEIZE);
628
		if (pause) sleep_ms(SEIZE_PAUSE);
629 630
		return;
	}
631
#endif
632

633 634
	if (tone_mode == MODE_MF) {
		switch (key) {
635 636 637 638 639 640 641 642 643
		case KEY_1:    play(tone_length, MF1, MF2); break;
		case KEY_2:    play(tone_length, MF1, MF3); break;
		case KEY_3:    play(tone_length, MF2, MF3); break;
		case KEY_4:    play(tone_length, MF1, MF4); break;
		case KEY_5:    play(tone_length, MF2, MF4); break;
		case KEY_6:    play(tone_length, MF3, MF4); break;
		case KEY_7:    play(tone_length, MF1, MF5); break;
		case KEY_8:    play(tone_length, MF2, MF5); break;
		case KEY_9:    play(tone_length, MF3, MF5); break;
644
		case KEY_STAR: play(KP_LENGTH, MF3, MF6); break;   /* KP */
645
		case KEY_0:    play(tone_length, MF4, MF5); break;
646
		case KEY_HASH: play(tone_length, MF5, MF6); break; /* ST */
647
#ifdef KEYS_16
648 649 650 651
		case KEY_A:    play(tone_length,  MF2, MF6); break; /* Code 12 */
		case KEY_B:    play(tone_length, MF4, MF6); break; /* KP2 */
		case KEY_C:    play(tone_length,  MF1, MF6); break; /* Code 11 */
		case KEY_D:    play(SEIZE_LENGTH, SEIZE, SEIZE); break; /* Seize */
652
#endif
653
		}
654
#ifdef KEYS_16
655
		if (key == KEY_D && pause)
656 657
			sleep_ms(SEIZE_PAUSE);
		else
658
#endif
659
			if (pause) sleep_ms(tone_length);
660 661
	} else if (tone_mode == MODE_DTMF) {
		switch (key) {
662 663 664 665 666 667 668 669 670 671 672 673
		case KEY_1:    play(tone_length, DTMF_ROW1, DTMF_COL1); break;
		case KEY_2:    play(tone_length, DTMF_ROW1, DTMF_COL2); break;
		case KEY_3:    play(tone_length, DTMF_ROW1, DTMF_COL3); break;
		case KEY_4:    play(tone_length, DTMF_ROW2, DTMF_COL1); break;
		case KEY_5:    play(tone_length, DTMF_ROW2, DTMF_COL2); break;
		case KEY_6:    play(tone_length, DTMF_ROW2, DTMF_COL3); break;
		case KEY_7:    play(tone_length, DTMF_ROW3, DTMF_COL1); break;
		case KEY_8:    play(tone_length, DTMF_ROW3, DTMF_COL2); break;
		case KEY_9:    play(tone_length, DTMF_ROW3, DTMF_COL3); break;
		case KEY_STAR: play(tone_length, DTMF_ROW4, DTMF_COL1); break;
		case KEY_0:    play(tone_length, DTMF_ROW4, DTMF_COL2); break;
		case KEY_HASH: play(tone_length, DTMF_ROW4, DTMF_COL3); break;
674
#ifdef KEYS_16
675 676 677 678
		case KEY_A:    play(tone_length, DTMF_ROW1, DTMF_COL4); break;
		case KEY_B:    play(tone_length, DTMF_ROW2, DTMF_COL4); break;
		case KEY_C:    play(tone_length, DTMF_ROW3, DTMF_COL4); break;
		case KEY_D:    play(tone_length, DTMF_ROW4, DTMF_COL4); break;
679
#endif
680
		}
681
		if (pause) sleep_ms(tone_length);
682 683
	} else if (tone_mode == MODE_REDBOX) {
		switch (key) {
684
		case KEY_1: play(66, RB1, RB2);	/* US Nickel */
David Griffith's avatar
David Griffith committed
685
			break;
686
		case KEY_2: play(66, RB1, RB2);	/* US Dime */
687
			sleep_ms(66);
688
			play(66, RB1, RB2);
689
			break;
690
		case KEY_3: play(33, RB1, RB2);	/* US Quarter */
691
			sleep_ms(33);
692
			play(33, RB1, RB2);
693
			sleep_ms(33);
694
			play(33, RB1, RB2);
695
			sleep_ms(33);
696
			play(33, RB1, RB2);
697
			sleep_ms(33);
698
			play(33, RB1, RB2);
David Griffith's avatar
David Griffith committed
699
			break;
700
		case KEY_4: play(60, RB2, RB2);	/* Canada nickel */
David Griffith's avatar
David Griffith committed
701
			break;
702
		case KEY_5: play(60, RB2, RB2);	/* Canada dime */
703
			sleep_ms(60);
704
			play(60, RB2, RB2);
705 706
			sleep_ms(60);
			break;
707
		case KEY_6: play(33, RB2, RB2);	/* Canada quarter */
708
			sleep_ms(33);
709
			play(33, RB2, RB2);
710
			sleep_ms(33);
711
			play(33, RB2, RB2);
712
			sleep_ms(33);
713
			play(33, RB2, RB2);
714
			sleep_ms(33);
715
			play(33, RB2, RB2);
716 717
			sleep_ms(33);
			break;
718
		case KEY_7: play(200, UKRB, UKRB);	/* UK 10 pence */
719
			break;
720
		case KEY_8: play(350, UKRB, UKRB);  	/* UK 50 pence */
David Griffith's avatar
David Griffith committed
721
			break;
722
		}
723
		if (pause) sleep_ms(REDBOX_PAUSE);
David Griffith's avatar
David Griffith committed
724 725
	} else if (tone_mode == MODE_GREENBOX) {
		switch(key) {
726 727
		/* Using 2600 wink */
		case KEY_1: play(90, SEIZE, SEIZE);	/* Coin collect */
David Griffith's avatar
David Griffith committed
728
			sleep_ms(60);
729
			play(900, MF1, MF3);
David Griffith's avatar
David Griffith committed
730
			break;
731
		case KEY_2: play(90, SEIZE, SEIZE);	/* Coin return */
David Griffith's avatar
David Griffith committed
732
			sleep_ms(60);
733
			play(900, MF3, MF6);
David Griffith's avatar
David Griffith committed
734
			break;
735
		case KEY_3: play(90, SEIZE, SEIZE);	/* Ringback */
David Griffith's avatar
David Griffith committed
736
			sleep_ms(60);
737
			play(900, MF1, MF6);
David Griffith's avatar
David Griffith committed
738
			break;
739
		case KEY_4: play(90, SEIZE, SEIZE);	/* Operator attached */
David Griffith's avatar
David Griffith committed
740
			sleep_ms(60);
741
			play(700, MF4, MF5);
David Griffith's avatar
David Griffith committed
742
			break;
743
		case KEY_5: play(90, SEIZE, SEIZE);	/* Operator released */
David Griffith's avatar
David Griffith committed
744
			sleep_ms(60);
745
			play(700, MF2, MF5);
David Griffith's avatar
David Griffith committed
746
			break;
747 748
		case KEY_6: play(90, SEIZE, SEIZE);	/* Operator release */
			sleep_ms(60);			/* and coin collect */
749
			play(700, MF5, MF6);
David Griffith's avatar
David Griffith committed
750
			break;
751 752
		/* With MF "8" (900 Hz + 1500 Hz) wink */
		case KEY_7: play(90, MF2, MF5);		/* Coin collect */
David Griffith's avatar
David Griffith committed
753
			sleep_ms(60);
754
			play(900, MF1, MF3);
David Griffith's avatar
David Griffith committed
755
			break;
756
		case KEY_8: play(90, MF2, MF5);		/* Coin return */
David Griffith's avatar
David Griffith committed
757
			sleep_ms(60);
758
			play(900, MF3, MF6);
David Griffith's avatar
David Griffith committed
759
			break;
760
		case KEY_9: play(90, MF2, MF5);		/* Ringback */
David Griffith's avatar
David Griffith committed
761
			sleep_ms(60);
762
			play(900, MF1, MF6);
David Griffith's avatar
David Griffith committed
763
			break;
764
		case KEY_STAR: play(90, MF2, MF5);	/* Operator attached */
David Griffith's avatar
David Griffith committed
765
			sleep_ms(60);
766
			play(700, MF3, MF5);
David Griffith's avatar
David Griffith committed
767
			break;
768
		case KEY_0: play(90, MF2, MF5);		/* Operator released */
David Griffith's avatar
David Griffith committed
769
			sleep_ms(60);
770
			play(700, MF2, MF5);
David Griffith's avatar
David Griffith committed
771
			break;
772 773
		case KEY_HASH: play(90, MF2, MF5);	/* Operator release */
			sleep_ms(60);			/* and coin collect */
774
			play(700, MF5, MF6);
David Griffith's avatar
David Griffith committed
775
			break;
David Griffith's avatar
David Griffith committed
776
		}
777
		if (pause) sleep_ms(GREENBOX_PAUSE);
778 779 780 781 782 783 784 785 786 787 788 789 790
	} else if (tone_mode == MODE_PULSE) {
		switch (key) {
		case KEY_1: pulse(1); break;
		case KEY_2: pulse(2); break;
		case KEY_3: pulse(3); break;
		case KEY_4: pulse(4); break;
		case KEY_5: pulse(5); break;
		case KEY_6: pulse(6); break;
		case KEY_7: pulse(7); break;
		case KEY_8: pulse(8); break;
		case KEY_9: pulse(9); break;
		case KEY_0: pulse(10); break;
		}
791
		if (pause) sleep_ms(PULSE_PAUSE);
792
	}
793
	return;
794
} /* void process_key(uint8_t key, bool pause) */
795

David Griffith's avatar
David Griffith committed
796

797
#ifdef KEYS_13
798
/*
799
 * uint8_t getkey(void)
800 801 802 803 804 805 806 807 808
 *
 * Returns the number of key pressed (1-13) or 0 if no key was pressed
 *
 * The resistor ladder feeds a voltage ranging from 0 VDC up to around
 * 4.64 VDC into the ADC pin.  The AVR then samples it and gives an
 * 8-bit value proportional to the voltage as compared to Vdd.  Then we
 * check to see what range that value falls into and thus we know which
 * button was pressed.
 *
809 810 811
 * Any ADC value less than 13 (used to be 9) is essentially 0 VDC
 * because of the pull-down resistor, with some margin for noise.  This
 * means that no key has been pressed.
812
 *
813 814 815 816
 * Further reading:
 *    https://learn.sparkfun.com/tutorials/voltage-dividers
 *    http://www.marcelpost.com/wiki/index.php/ATtiny85_ADC
 *
817
 */
818
uint8_t getkey(void)
819
{
820
	uint8_t voltage;
821
	while (1) {
822 823 824
		ADCSRA |= (1 << ADSC);		/* start ADC measurement */
		while (ADCSRA & (1 << ADSC) );	/* wait till conversion complete */
		sleep_ms(DEBOUNCE_TIME);	/* delay for debounce */
825
		voltage = ADCH;
826 827 828 829
		ADCSRA |= (1 << ADSC);		/* start ADC measurement */
		while (ADCSRA & (1 << ADSC) );	/* wait till conversion complete */
		if (voltage != ADCH) continue;	/* bouncy result, try again */
		if (voltage <  13) return 0;	/* no key has been pressed */
830

831 832
		/* If we made it this far, then we've got something valid */
		/* These values calculated with Vdd = 5 volts DC */
833

834
		/* 4.64 volts.  ADC value = 246 */
835
		if (voltage > 233 ) return KEY_SEIZE;
836
		/* 4.29 volts.  ADC value = 219 */
837
		if (voltage > 211 && voltage <= 232) return KEY_1;
838
		/* 3.93 volts.  ADC value = 201 */
839
		if (voltage > 192 && voltage <= 210) return KEY_2;
840
		/* 3.57 volts.  ADC value = 183 */
841
		if (voltage > 174 && voltage <= 191) return KEY_3;
842
		/* 3.21 volts.  ADC value = 165 */
843
		if (voltage > 155 && voltage <= 173) return KEY_4;
844
		/* 2.86 volts.  ADC value = 146 */
845
		if (voltage > 137 && voltage <= 154) return KEY_5;
846
		/* 2.50 volts.  ADC value = 128 */
847
		if (voltage > 119 && voltage <= 136) return KEY_6;
848
		/* 2.14 volts.  ADC value = 110 */
849
		if (voltage > 101 && voltage <= 118) return KEY_7;
850
		/* 1.79 volts.  ADC value = 91 */
851
		if (voltage > 82  && voltage <= 100) return KEY_8;
852
		/* 1.42 volts.  ADC value = 73 */
853
		if (voltage > 64  && voltage <=  81) return KEY_9;
854
		/* 1.07 volts.  ADC value = 55 */
855
		if (voltage > 46  && voltage <=  63) return KEY_STAR;
856
		/* 0.71 volts.  ADC value = 37 */
857
		if (voltage > 27  && voltage <=  45) return KEY_0;
858
		/* 0.357 volts.  ADC value = 18 */
859
		if (voltage > 16   && voltage <=  26) return KEY_HASH;
860 861
		/* We shouldn't get past here, */
		/* but if we do, treat it like no key detected. */
862 863
		break;
	}
864
	return KEY_NOTHING;
865
}  /* uint8_t getkey(void) */
866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897


/*
 * void process_longpress(uint8_t key)
 *
 * 13-key version
 *
 * A long press will do either of two things.  A long press on the 2600
 * key will toggle the bluebox between normal and memory playback modes.
 * A long press on any other key while in normal mode will save the last
 * EEPROM_CHUNK_SIZE - 1 keystrokes to EEPROM (first byte is for mode).
 * The only long press while in memory playback mode that is honored is
 * 2600, which will toggle the bluebox back to normal mode.
 *
 */
void process_longpress(uint8_t key)
{
	bool just_flipped = FALSE;
	bool just_wrote = FALSE;

	longpress_counter = LONGPRESS_TIME;
	longpress_on = TRUE;

	while (key == getkey() && key != KEY_NOTHING) {
		if (longpress_flag) {
			/* Long press on 2600 toggles playback mode. */
			if (key == KEY_SEIZE) {
				/* Clear buffer when toggling playback. */
				rbuf_init(&rbuf);
				just_flipped = TRUE;
				if (playback_mode == FALSE) {
					playback_mode = TRUE;
898 899
					play(75, PLAYBACK_FLIP_LOW_TONE, 0);
					play(75, PLAYBACK_FLIP_HIGH_TONE, 0);
900 901
				} else {
					playback_mode = FALSE;
902 903
					play(75, PLAYBACK_FLIP_HIGH_TONE, 0);
					play(75, PLAYBACK_FLIP_LOW_TONE, 0);
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922
				}
			} else { /* Store the buffer in EEPROM, */
				 /* but don't store when in playback mode. */
				if (!playback_mode) {
					eeprom_store(key);
					just_wrote = TRUE;
				}
			}
		}
	}
	longpress_on = FALSE;

	/* If a long press was not detected, */
	/* store the key in the circular buffer.*/
	if (!playback_mode && !just_flipped && !just_wrote)
		rbuf_insert(&rbuf, key);
	just_flipped = FALSE;
	just_wrote = FALSE;
	return;
923
} /* void process_longpress(uint8_t key) */
924
#else	/* We're using a 16-key keypad */
925 926
#error 16-keys not yet implemented
#endif
927

928

929
/*
930 931 932 933
 * PB0 is audio output.
 * PB1 is LED output.  Pull down to light LEDs.
 * PB2 is input from the resistor ladder.
 * PB3 and PB4 are for the crystal.
934 935
 *
 */
936 937 938 939 940
void init_ports(void)
{
	cli();
	DDRB  = 0b11100011;
	TIMSK |= (1<<TOIE0);
941
	PORTB &= ~(1 << PB1);	/* Make sure LEDs are off. */
942
	sei();
943
	return;
944 945
}

946

947 948 949 950 951 952 953 954 955 956 957
/*
 * void init_adc(void)
 *
 * ADC prescaler needs to be set so that the ADC input frequency is
 * between 50 -- 200kHz
 *
 * For more information, see table 17.5 "ADC Prescaler Selections" in
 * chapter 17.13.2 "ADCSRA – ADC Control and Status Register A"
 * (pages 140 and 141 on the complete ATtiny25/45/85 datasheet,
 * Rev. 2586M–AVR–07/10)
 *
958 959
 * http://www.atmel.com/images/atmel-2586-avr-8-bit-microcontroller-attiny25-attiny45-attiny85_datasheet.pdf
 *
David Griffith's avatar
David Griffith committed
960 961 962
 * Further reading:
 *    http://www.marcelpost.com/wiki/index.php/ATtiny85_ADC
 *
963
 */
964
void init_adc(void)
965
{
966 967 968 969 970 971
	/*
	 * 8-bit resolution
	 * set ADLAR to 1 to enable the left-shift result
	 * (only bits ADC9..ADC2 are available), then
	 * only reading ADCH is sufficient for 8-bit results (256 values)
	 */
972
	ADMUX =
973 974 975 976 977 978 979 980 981 982 983
		(1 << ADLAR) |	/* left shift result */
		(0 << REFS1) |	/* set ref voltage to VCC, bit 1 */
		(0 << REFS0) |	/* set ref voltage to VCC, bit 0 */
		(0 << MUX3)  |	/* use ADC1 for input (PB2), MUX bit 3 */
		(0 << MUX2)  |  /* use ADC1 for input (PB2), MUX bit 2 */
		(0 << MUX1)  |  /* use ADC1 for input (PB2), MUX bit 1 */
		(1 << MUX0);	/* use ADC1 for input (PB2), MUX bit 0 */

	/* Using a 20MHz crystal.
	 * Setting prescaler to 128 gives me a frequency of 156.250 kHz
	 */
984
	ADCSRA =
985 986 987 988
		(1 << ADEN)  |	/* enable ADC */
		(1 << ADPS2) |	/* set prescaler to 128, bit 2 */
		(1 << ADPS1) |	/* set prescaler to 128, bit 1 */
		(1 << ADPS0);	/* set prescaler to 128, bit 0 */
989
	return;
990
} /* void init_adc(void) */
991 992 993 994 995 996 997


/*
 * void play(uint32_t duration, uint32_t freq_a, uint32_t freq_b)
 *
 * Plays a pair of tones (in Hz) for the duration (in ms) specified.
 *
998 999 1000 1001
 * There are two ways to play a single tone:
 *   1) make freq_a and freq_b the same
 *   2) make freq_b zero
 *
1002 1003 1004 1005 1006 1007 1008 1009
 */
void play(uint32_t duration, uint32_t freq_a, uint32_t freq_b)
{
	uint32_t tmp_a = SAMPLES_PER_HERTZ_TIMES_256;
	uint32_t tmp_b = SAMPLES_PER_HERTZ_TIMES_256;

	tmp_a *= freq_a;
	tone_a_step = tmp_a / 256;
1010 1011 1012 1013
	if (freq_b == 0)
		tmp_b *= freq_a;
	else
		tmp_b *= freq_b;
1014 1015 1016 1017
	tone_b_step = tmp_b / 256;

	tone_a_place = 0;
	tone_b_place = 0;
1018 1019

	PORTB |= (1 << PB1);	/* Turn on LEDs. */
1020 1021 1022
	tones_on = TRUE;
	sleep_ms(duration);
	tones_on = FALSE;
1023 1024
	PORTB &= ~(1 << PB1);	/* Turn off LEDs. */

1025
	return;
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
}


/*
 * void pulse(uint8_t count)
 *
 * Send a series of 2600hz pulses with the same timing as a rotary dialer
 * This pre-dates the US R1/MF signalling system.
 * This was how John Draper (aka Cap'n Crunch) and Joe Engressia Jr.
 * (aka Joybubbles) were able to phreak using a whistled 2600hz tone.
 *
 */
void pulse(uint8_t count)
{
	uint8_t	i;

	for (i = 0; i < count; i++) {
1043 1044
		play(PULSE_DURATION, SEIZE, 0);
		sleep_ms(PULSE_INTERVAL);
1045
	}
1046
	return;
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
}


/*
 * void sleep_ms(uint16_t milliseconds)
 *
 * For some strange reason, _delay_ms() and _delay_us() run too slow by
 * a factor of around four.  I don't know if this is particular to the
 * ATtiny line or if there's a problem in the Linux AVR development
 * tools.  Anyhow, this function simply holds up execution by the
 * supplied number of milliseconds.  The tick() function can be
 * convenient for monitoring buttons and doing debouncing.  More on that
 * later.
 *
1061 1062 1063
 * Further reading:
 *    http://repos.borg.ch/projects/avr_leds/trunk/ws2811/avr/big-led-string.c
 *
1064 1065 1066 1067 1068
 */
void sleep_ms(uint16_t milliseconds)
{
	while( milliseconds > 0 ) {
		if( millisec_flag ) {
1069
			millisec_flag = FALSE;
1070 1071 1072 1073
			milliseconds--;
			tick();
		}
	}
1074
	return;
1075 1076 1077 1078 1079
}

void tick(void) {}


1080 1081 1082 1083 1084 1085 1086 1087
/*
 * ISR(TIM0_OVF_vect)
 *
 * Here we set up a timer to present sine data to an oscillator.
 * This produces a pulse-width-modulated wave that creates an
 * approximation of a sine wave.  This is smoothed out with a low-pass
 * filter after the signal exits the microcontroller.
 *
1088 1089
 * This timer also provides the timing for the sleep_ms() function.
 *
1090 1091 1092
 * Further reading:
 *    https://en.wikipedia.org/wiki/Pulse-width_modulation
 *    https://learn.sparkfun.com/tutorials/pulse-width-modulation
David Griffith's avatar
David Griffith committed
1093
 *
1094
 */
1095 1096 1097
ISR(TIM0_OVF_vect)
{
	if (tones_on) {
1098 1099
	OCR0A = (pgm_read_byte(&(sine_table[(tone_a_place >> STEP_SHIFT)])) +
		pgm_read_byte(&(sine_table[(tone_b_place >> STEP_SHIFT)]))) / 2;
1100 1101 1102 1103 1104 1105
	tone_a_place += tone_a_step;
	tone_b_place += tone_b_step;
	if(tone_a_place >= (SINE_SAMPLES << STEP_SHIFT))
		tone_a_place -= (SINE_SAMPLES << STEP_SHIFT);
	if(tone_b_place >= (SINE_SAMPLES << STEP_SHIFT))
		tone_b_place -= (SINE_SAMPLES << STEP_SHIFT);
1106
	} else OCR0A = SINE_MIDPOINT; /* Send 0V to PWM output */
1107

1108
	/* Count milliseconds */
1109 1110 1111
	millisec_counter--;
	if(millisec_counter == 0) {
		millisec_counter = OVERFLOW_PER_MILLISEC;
1112
		millisec_flag = TRUE;
1113

David Griffith's avatar
David Griffith committed
1114 1115
		/*
		 * This is a secondary millisecond counter that is turned
1116 1117 1118 1119
		 * on only when we're waiting for a key to be pressed
		 * and held.  If it times out, then we set a flag to let
		 * the main loop know that a long press has occurred.
		 */
1120 1121 1122 1123 1124 1125 1126 1127
		if (longpress_on) {
			longpress_counter--;
			longpress_flag = 0;
			if (longpress_counter == 0) {
				longpress_counter = LONGPRESS_TIME;
				longpress_flag = 1;
			}
		}
1128
	}
1129
	return;
1130
} /* ISR(TIM0_OVF_vect) */
1131 1132 1133 1134 1135 1136 1137


/*
 * Below are functions for implementing a ring buffer.
 * They was adapted from Dean Camera's sample code at
 * http://www.fourwalledcubicle.com/files/LightweightRingBuff.h
 *
1138 1139 1140 1141
 * The atomic blocks here are probably not necessary for this particular
 * program, but since it's likely this code will be borrowed for other
 * things, I think it's best to do things right.
 *
1142 1143 1144
 * Further reading:
 *    https://en.wikipedia.org/wiki/Circular_buffer
 *
1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
 */

/*
 * Initializes a ring buffer ready for use. Buffers must be initialized
 * via this function before any operations are called upon them. Already
 * initialized buffers may be reset by re-initializing them using this
 * function.
 *
 * Parameter:
 *	OUT buffer: Pointer to a ring buffer structure to initialize
 *
 */
static inline void rbuf_init(rbuf_t* const buffer)
{
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
		buffer->in    = buffer->buffer;
		buffer->out   = buffer->buffer;
		buffer->count = 0;
	}
1164
	return;
1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234
}


/*
 * Retrieves the minimum number of bytes stored in a particular buffer.
 * This value is computed by entering an atomic lock on the buffer while
 * the IN and OUT locations are fetched, so that the buffer cannot be
 * modified while the computation takes place. This value should be
 * cached when reading out the contents of the buffer, so that as small
 * a time as possible is spent in an atomic lock.
 *
 * NOTE: The value returned by this function is guaranteed to only be
 *   the minimum number of bytes stored in the given buffer; this value
 *   may change as other threads write new data and so the returned
 *   number should be used only to determine how many successive reads
 *   may safely be performed on the buffer.
 *
 * Parameter:
 *	OUT buffer: Pointer to a ring buffer structure whose count is
 *		    to be computed.
 *
 */
static inline rbuf_count_t rbuf_getcount(rbuf_t* const buffer)
{
	rbuf_count_t count;
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
		count = buffer->count;
	}
	return count;
}


/*
 * Atomically determines if the specified ring buffer contains any data.
 * This should be tested before removing data from the buffer, to ensure
 * that the buffer does not underflow.
 *
 * If the data is to be removed in a loop, store the total number of
 * bytes stored in the buffer (via a call to the rbuf_getcount()
 * function) in a temporary variable to reduce the time spent in
 * atomicity locks.
 *
 * Parameters:
 *	IN/OUT buffer: Pointer to a ring buffer structure to insert into
 *	return: Boolean true if the buffer contains no free space, false
 *		otherwise.
 *
 */
static inline bool rbuf_isempty(rbuf_t* buffer)
{
	return (rbuf_getcount(buffer) == 0);
}


/*
 * Inserts an element into the ring buffer.
 *
 * NOTE: Only one execution thread (main program thread or an ISR) may
 *	 insert into a single buffer otherwise data corruption may
 *	 occur. Insertion and removal may occur from different execution
 *	 threads.
 *
 * Parameters:
 *	IN/OUT buffer: Pointer to a ring buffer structure to insert into.
 *	IN data: Data element to insert into the buffer.
 *
 */
static inline void rbuf_insert(rbuf_t* const buffer, const rbuf_data_t data)
{
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
1235 1236 1237
		*buffer->in = data;
		if (++buffer->in == &buffer->buffer[BUFFER_SIZE])
			buffer->in = buffer->buffer;
1238 1239
		buffer->count++;
	}
1240
	return;
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
}


/* Removes an element from the ring buffer.
 *
 * NOTE: Only one execution thread (main program thread or an ISR) may
 * remove from a single buffer otherwise data corruption may occur.
 * Insertion and removal may occur from different execution threads.
 *
 * Parameters:
 *	IN/OUT buffer: Pointer to a ring buffer structure to retrieve from.
 *	return: Next data element stored in the buffer.
 *
 */
static inline rbuf_data_t rbuf_remove(rbuf_t* const buffer)
{
1257
	rbuf_data_t data;
1258
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
1259 1260 1261
		data = *buffer->out;
		if (++buffer->out == &buffer->buffer[BUFFER_SIZE])
			buffer->out = buffer->buffer;
1262 1263 1264 1265
		buffer->count--;
	}
	return data;
}