92 lines
3.4 KiB
C
92 lines
3.4 KiB
C
/* Include file with DPCM data in it */
|
|
#include "allDigits.h"
|
|
#include <avr/pgmspace.h>
|
|
|
|
// Now define sample-table names used in digits file
|
|
// From here on, no matter what you call the samples,
|
|
// you can refer to them as "ONE_TABLE", etc.
|
|
#define ONE_TABLE DPCM_one_8000
|
|
#define TWO_TABLE DPCM_two_8000
|
|
#define THREE_TABLE DPCM_three_8000
|
|
#define FOUR_TABLE DPCM_four_8000
|
|
#define FIVE_TABLE DPCM_five_8000
|
|
#define SIX_TABLE DPCM_six_8000
|
|
#define SEVEN_TABLE DPCM_seven_8000
|
|
#define EIGHT_TABLE DPCM_eight_8000
|
|
#define NINE_TABLE DPCM_nine_8000
|
|
#define ZERO_TABLE DPCM_zero_8000
|
|
#define POINT_TABLE DPCM_point_8000
|
|
#define VOLTS_TABLE DPCM_volts_8000
|
|
#define INTRO_TABLE DPCM_talkingvoltmeter_8000
|
|
|
|
#define SPEECH_DELAY 2000 /* milliseconds */
|
|
|
|
/* --------------- Globals used by the ISR -------------- */
|
|
volatile uint8_t* thisTableP; /* points at the current speech table */
|
|
volatile uint16_t thisTableLength; /* length of current speech table */
|
|
|
|
volatile uint16_t sampleNumber; // sample index
|
|
volatile int8_t out, lastout; // output values
|
|
volatile uint8_t differentials[4] = {0,0,0,0};
|
|
const int8_t dpcmWeights[4] = {-12, -3, 3, 12};
|
|
|
|
|
|
/* These arrays let us choose a table (and its length) numerically */
|
|
const uint16_t tableLengths[] = { /* all sample tables are 8-bit */
|
|
sizeof(ZERO_TABLE), sizeof(ONE_TABLE), sizeof(TWO_TABLE),
|
|
sizeof(THREE_TABLE), sizeof(FOUR_TABLE), sizeof(FIVE_TABLE),
|
|
sizeof(SIX_TABLE), sizeof(SEVEN_TABLE), sizeof(EIGHT_TABLE),
|
|
sizeof(NINE_TABLE), sizeof(POINT_TABLE), sizeof(VOLTS_TABLE),
|
|
sizeof(INTRO_TABLE)
|
|
};
|
|
|
|
// Create an indexing table of all of the start addresses for
|
|
// each spoken digit. And then store this index in PROGMEM.
|
|
const uint8_t* const tablePointers[] PROGMEM = {
|
|
ZERO_TABLE, ONE_TABLE, TWO_TABLE, THREE_TABLE, FOUR_TABLE,
|
|
FIVE_TABLE, SIX_TABLE, SEVEN_TABLE, EIGHT_TABLE, NINE_TABLE,
|
|
POINT_TABLE, VOLTS_TABLE, INTRO_TABLE
|
|
};
|
|
|
|
void selectTable(uint8_t whichTable){
|
|
/* Set up global table pointer, lengths */
|
|
uint16_t pointerAddress;
|
|
thisTableLength = tableLengths[whichTable];
|
|
pointerAddress = (uint16_t) &tablePointers[whichTable];
|
|
thisTableP = (uint8_t*) pgm_read_word(pointerAddress);
|
|
}
|
|
|
|
/* Extra defines for the non-numeric values */
|
|
#define POINT 10
|
|
#define VOLTS 11
|
|
#define INTRO 12
|
|
|
|
|
|
///----------------- Init functions -------------------///
|
|
|
|
void initTimer0(void){
|
|
// Timer 0 Configured for free-running PWM Audio Output
|
|
TCCR0A |= (1<<WGM00) | (1<<WGM01); /* fast PWM mode */
|
|
TCCR0A |= (1<<COM0A0) | (1<<COM0A1); /* output on PD6/OC0A */
|
|
TCCR0B = (1<<CS00); /* fastest clock */
|
|
OCR0A = 128 ; /* initialize mid-value */
|
|
SPEAKER_DDR |= (1<<SPEAKER); /* output PD6 / OC0A */
|
|
}
|
|
|
|
void initTimer2(void){
|
|
// Timer 2 loads OCR0A, provides sampling frequency
|
|
TCCR2A = (1<<WGM21); /* CTC, count to OCR2A */
|
|
TIMSK2 = (1<<OCIE2A); /* turn on compare interrupt */
|
|
OCR2A = 128; /* controls sample playback frequency */
|
|
/* note: no clock source selected yet, so won't start up */
|
|
}
|
|
|
|
void initADC(void){
|
|
// ADC for Voltmeter function
|
|
ADMUX |= (0b00001111 & PC5); /* set mux to ADC5 */
|
|
DIDR0 |= _BV(ADC5D); /* turn off digital circuitry on PC5 */
|
|
ADMUX |= (1 << REFS0); /* reference voltage is AVCC, 5V */
|
|
ADCSRA |= (1 << ADPS1) | (1 << ADPS2); /* ADC clock prescaler /64 */
|
|
ADCSRA |= (1 << ADEN); /* enable ADC */
|
|
}
|