Hi,
I am trying to build a code which reads HEX data(converted from .wav audio file PCM ,8Khz,mono), which is stored in EEPROM via I2C. I am using the source code form eZ430-SPEECH. The idea here in the source code from "TI" is to generate PWM signals on TIMERA0 according to stored hex values in EEPROM. Pin1.1 TA0.0 is used in OUTMODE_3 set/reset mode to provide PWM. I could able to go through the code and can see the process flow (step by step debug), But I was unable to listen any sound when I connect a simple headphone to P1.1 and GND pins. Please help me in understanding the process of Audio Playback. Here I am attaching my code and the HEX file of generated audio data. please comment on this. I am using CCS5.2
I have figured out the basic flaw in the code and modified it, I have set PWM functionality to TA0.0 ( P1.1 ) which cannot do it (PWM), I have changed it to P1.2 and now I can see PWM signals over the scope. But the sound dnt make any sense its just Gibberish. Here is the new modified code please say me where I am going wrong.
#include <msp430.h>
#include <stdint.h>
#include "I2CMaster.h"
typedef unsigned char u8_t;
typedef unsigned short int u16_t;
typedef signed char i8_t;
typedef short int i16_t;
// Data buffer for I2C ops.
#define BUFF_SZ 64
uint8_t Buffer[ BUFF_SZ ];
// If this variable is locally declared as uint32_t in main it is not
// properly allocated/handled by the compiler unless optimization is
// turned on
uint32_t ImgSize = 0;
uint8_t uAvgCntr;
uint8_t uAudioSample1;
uint8_t uAudioSample2;
int iAudioSampleDifference;
uint32_t lAudioSampleCnt;
uint32_t lAudioSampleLength;
void initTA0(void)
{
// Initialise Timer_A for PWM output
TACTL = TASSEL_2 | ID_1 | TACLR; //|TAIE; // clock = SMCLK /2 = 16 MHz / 2
// overflow interrupt enabled
TACCTL1 = CM_0 | OUTMOD_7 | CCIE; // CM_0: Compare mode (no capture mode)
// OUTMOD_7 set/rest mode PWm
// CCIE: Compare Interrupt Enabled
TACCR0 = 0xFF; // 8-bit counter from 00h to FFh---sri Notes: Usually this goes as PWM period
// Set P1.2 as output for PWM signals
//sri Notes: P1.1 cannot be used for PWM output
P1DIR |= BIT2; // Pin4-P1.2/TA0.1 is output
P1SEL |= BIT2; // Pin4-P1.2/TA0.1 is TA1 output WITH PWM functionality
}
#define StartTimer() TACTL |= MC_1; //START TIMER IN UP MODE
#define StopTimer() TACTL |= MC_0;
void readImgSz(void)
{
// Read the header of the binary image to get its size. Start
// reading from memory address 0.
Buffer[0] = 0x00;
Buffer[1] = 0x00;
I2CWrite( EEPROM_ADDR , Buffer , 2 );
I2CRead( EEPROM_ADDR , Buffer , 4 );
// 32-bit size value
ImgSize = (uint32_t) Buffer[0];
ImgSize <<= 8;
ImgSize |= (uint32_t) Buffer[1];
ImgSize <<= 8;
ImgSize |= (uint32_t) Buffer[2];
ImgSize <<= 8;
ImgSize |= (uint32_t) Buffer[3];
}
void main (void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
DCOCTL = CALDCO_16MHZ; // Select DCO@16MHz as clock sources
BCSCTL1 = CALBC1_16MHZ;
I2CInit(); // Initialise I2C
_enable_interrupt(); // Enable interrupts
initTA0(); //Initialise TimerA
while(1)
{
readImgSz();
I2CRead( EEPROM_ADDR , Buffer , 2 );
uAudioSample1 = Buffer[0];
uAudioSample2 = Buffer[1];
uAvgCntr = 0;
StartTimer();
for (lAudioSampleCnt = ImgSize-1; lAudioSampleCnt > 0; lAudioSampleCnt--)
{
__bis_SR_register(LPM0_bits + GIE); // LPM0: keep DCO running
I2CRead( EEPROM_ADDR , Buffer , 1 );
uAudioSample1 = uAudioSample2;
uAudioSample2 = Buffer[0];
}
StopTimer();
}
}
//******************************************************************************
// Timer A1 interrupt service routine
//******************************************************************************
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer0_A1_ISR (void)
{ // Timer interrupt (PWM, one sample)
switch (__even_in_range(TAIV,10))
{
case 2: // Vector 2: TACCR1
iAudioSampleDifference = (int) uAudioSample2 - (int) uAudioSample1;
if (iAudioSampleDifference > 68)
{
TACTL &= ~TAIFG; // clear overflow flag TAIFG IFG
TACTL |= TAIE; // enable overflow interrupt TAIFG
TACCTL1 &= ~CCIE; // turn off TACCR1 IFG
}
switch (__even_in_range(uAvgCntr,6))
{
case 0: TACCR1 = (uAudioSample1
+ uAudioSample1
+ uAudioSample1
+ uAudioSample2) >> 2;
break;
case 2: TACCR1 = (uAudioSample1
+ uAudioSample2) >> 1;
break;
case 4: TACCR1 = (uAudioSample1
+ uAudioSample2
+ uAudioSample2
+ uAudioSample2) >> 2;
break;
case 6: TACCR1 = uAudioSample2;
__bic_SR_register_on_exit(LPM4_bits);
// Clear all LPM bits from 0(SR)
// this restarts audio output loop
// and read next audio sample from
// SPI-Flash memory
break;
}
uAvgCntr+=2; // increment averaging counter (always by 2)
uAvgCntr = uAvgCntr & 0x06; // averaging counter range: 0, 2, 4, 6
break;
case 4: // Vector 4: TACCR2
break;
case 10: // Vector 10: TAIFG Flag
TACCTL1 &= ~CCIFG; // clear TACCR1 IFG
TACCTL1 |= CCIE; // enable TACCR1 IFG
TACTL &= ~TAIE; // turn off overflow interrupt TAIFG
break;
}
} // __interrupt void TimerA1 (void)