does not work yet. Sound starts but then stops after a few seconds, whole thing hangs. Published so as I can import through mbed CLI.

Dependencies:   mbed sinelookup SDFileSystem_Copy_of_mbed_version I2S

wolfson_3_wav.cpp

Committer:
roryhand
Date:
2018-10-01
Revision:
1:ec4e2020522c
Parent:
0:004cb0595aa8
Child:
2:05b426733282

File content as of revision 1:ec4e2020522c:


//  24/03/2018  update - I appear to be able to address the device and write something, as I am getting an ACK returned from the i2c write() function.
//however if i use the write function with 4 arguments (as opposed to just 1 argument) then it doesnt work
//only works with the 1 argument version!!!


//THIS VERSION WORKED, CHANGED SOME THINGS, THEN CHANGED THEM BACK.  NOW IT NO LONGER WORKS!!!!
#include "mbed.h"
#include "sinelookup.h" 
#include "I2S.h"   
#define sample_freq 48000
DigitalOut myled(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
Ticker sampletick;
Timer t;
#include "SDFileSystem.h"     
#include "WOLFSON_config.h"  
Serial pc(USBTX, USBRX); // tx, rx //FOR DEBUGGING PROGRAM USING GNU SCREEN
DigitalOut cs(p8);
I2S i2s(I2S_TRANSMIT,p5,p6,p7);
I2C i2c(p9, p10);
 
SDFileSystem sd(p11, p12, p13, p8, "sd"); // the new pinout that i am using

typedef struct uFMT_STRUCT{
  short comp_code;
  short num_channels;
  unsigned sample_rate;
  unsigned avg_Bps;
  short block_align;
  short sig_bps;
} FMT_STRUCT;

typedef struct uDATA_STRUCT {
  unsigned subchunk2_ID;
  unsigned subchunk2_size;
  char * data_buf;
}DATA_STRUCT;
short hello;
int i = 0;
int h = 0;
int bufflen = 1;
int buffer[1];
int AudioFormat, NumChannels, SampleRate, BitsPerSample ; 
char *slice_buf;
int *data_sptr;
int newvar;
//long long slice_value;
int slice_value;
FILE *my_wav;
FMT_STRUCT wav_format;
DATA_STRUCT wav_data;

Ticker flipper;
//test
void flip() {
    led2  = !led2;
}


void isr()
{

    //buffer[0] = (int*)data_sptr;
    //buffer[0] = newvar;
    //buffer[0] = sine16lookup[i];//>>1;//sine16lookup[i];//scale down volume a bit on amp//how would this scale down the volume a bit??
    //buffer[0] = *fp;
    //printf("value: %d",data_sptr);
    //i2s.write(buffer, 2);//Send next PWM value to amp
    }

    


void wm8731_setup(int chip_addr, int addr, int cmd){
    addr = addr << 1;
    addr = addr|((cmd >> 8 ))& 0x01;//mess around with order of operations
    cmd = cmd&0xFF;
    i2c.start();
    i2c.write( chip_addr );
    i2c.write( addr  );
    i2c.write( cmd );
    i2c.stop(); 
    }
    

void wm8731_config(void){
    wm8731_setup( WM8731_ADDRESS, WM8731_REG_RESET, _WM8731_RESET );//1
    wm8731_setup( WM8731_ADDRESS, WM8731_REG_LLINE_IN, _WM8731_LEFT_LINEIN );//2
    wm8731_setup( WM8731_ADDRESS, WM8731_REG_RLINE_IN, _WM8731_RIGHT_LINEIN );//3
    wm8731_setup( WM8731_ADDRESS, WM8731_REG_LHPHONE_OUT, _WM8731_LEFT_HP );//4 
    wm8731_setup( WM8731_ADDRESS, WM8731_REG_RHPHONE_OUT, _WM8731_RIGHT_HP );//5   
    wm8731_setup( WM8731_ADDRESS, WM8731_REG_ANALOG_PATH, _WM8731_ANALOGAUDIO );//6   
    wm8731_setup( WM8731_ADDRESS, WM8731_REG_DIGITAL_PATH, _WM8731_DIGITALAUDIO );//7   
    wm8731_setup( WM8731_ADDRESS, WM8731_REG_PDOWN_CTRL, _WM8731_POWER );//8   
    wm8731_setup( WM8731_ADDRESS, WM8731_REG_DIGITAL_IF, _WM8731_DAIF );//9   
    wm8731_setup( WM8731_ADDRESS, WM8731_REG_SAMPLING_CTRL, _WM8731_SAMPLING );//10
    }    
    
void wm8731_configTEST(void){
    int addr = WM8731_REG_RESET;
    int cmd = _WM8731_RESET;
    addr = addr << 1;
    addr = addr|((cmd >> 8 ))& 0x01;//mess around with order of operations
    cmd = cmd&0xFF;
    i2c.start();
    i2c.write( WM8731_ADDRESS );
    i2c.write( addr  );
    i2c.write( cmd );
    i2c.stop();

    addr = WM8731_REG_LLINE_IN;
    cmd = _WM8731_LEFT_LINEIN;
    addr = addr << 1;
    addr = addr|((cmd >> 8 )) & 0x01;
    cmd = cmd&0xFF;
    i2c.start();
    i2c.write( WM8731_ADDRESS );//take Fergus' suggestion and declare these to known values EARLIER in program
    i2c.write( addr );
    i2c.write( cmd );
    i2c.stop();
    
    
    addr = WM8731_REG_RLINE_IN;
    cmd = _WM8731_RIGHT_LINEIN;
    addr = addr << 1;
    addr = addr|((cmd >> 8 )) & 0x01;
    cmd = cmd&0xFF;
    i2c.start();
    i2c.write( WM8731_ADDRESS );//take Fergus' suggestion and declare these to known values EARLIER in program
    i2c.write( addr );
    i2c.write( cmd );
    i2c.stop();
    
       
    //4
    addr = WM8731_REG_LHPHONE_OUT;
    cmd = _WM8731_LEFT_HP;
    addr = addr << 1;
    addr = addr|((cmd >> 8 )) & 0x01;
    cmd = cmd&0xFF;
    i2c.start();
    i2c.write( WM8731_ADDRESS );
    i2c.write( addr );//WM8731_REG_LHPHONE_OUT, _WM8731_LEFT_HP   
    i2c.write(cmd);   
    i2c.stop();
      
    //5
    addr = WM8731_REG_RHPHONE_OUT;
    cmd = _WM8731_RIGHT_HP;
    addr = addr << 1;
    addr = addr|((cmd >> 8 )) & 0x01;
    cmd = cmd&0xFF;
    i2c.start();
    i2c.write( WM8731_ADDRESS );//WM8731_REG_RHPHONE_OUT, _WM8731_RIGHT_HP 
    i2c.write( addr );
    i2c.write( cmd );
    i2c.stop();
  
    
    //6
    addr = WM8731_REG_ANALOG_PATH;
    cmd = _WM8731_ANALOGAUDIO;
    addr = addr << 1;
    addr = addr|((cmd >> 8 )) & 0x01;
    cmd = cmd&0xFF;
    i2c.start();
    i2c.write( WM8731_ADDRESS );//WM8731_REG_ANALOG_PATH, _WM8731_ANALOGAUDIO
    i2c.write( addr );
    i2c.write( cmd );
    i2c.stop();
    
    //7
    addr = WM8731_REG_DIGITAL_PATH;
    cmd = _WM8731_DIGITALAUDIO;
    addr = addr << 1;
    addr = addr|((cmd >> 8 )) & 0x01;
    cmd = cmd&0xFF;
    i2c.start();
    i2c.write( WM8731_ADDRESS );//WM8731_REG_DIGITAL_PATH, _WM8731_DIGITALAUDIO
    i2c.write( addr  );
    i2c.write( cmd );
    i2c.stop();
    
    //8
    addr = WM8731_REG_PDOWN_CTRL;
    cmd = _WM8731_POWER;
    addr = addr << 1;
    addr = addr|((cmd >> 8 )) & 0x01;
    cmd = cmd&0xFF;
    i2c.start();
    i2c.write( WM8731_ADDRESS );//WM8731_REG_PDOWN_CTRL, _WM8731_POWER)
    i2c.write( addr  );
    i2c.write( cmd );
    i2c.stop();
    
    
    //9
    addr = WM8731_REG_DIGITAL_IF;
    cmd = _WM8731_DAIF;
    addr = addr << 1;
    addr = addr|((cmd >> 8 )) & 0x01;
    cmd = cmd&0xFF;
    i2c.start();
    i2c.write( WM8731_ADDRESS );
    i2c.write( addr  );//WM8731_REG_DIGITAL_IF, _WM8731_DAIF
    i2c.write( cmd );
    i2c.stop();

   
    //10
    addr = WM8731_REG_SAMPLING_CTRL;
    cmd = _WM8731_SAMPLING;
    addr = addr << 1;
    addr = addr|((cmd >> 8 )) & 0x01;
    cmd = cmd&0xFF;
    i2c.start();
    i2c.write( WM8731_ADDRESS );//WM8731_REG_SAMPLING_CTRL, _WM8731_SAMPLING
    i2c.write( addr  );
    i2c.write( cmd );
    i2c.stop();
    
    
   
    
    //11
    addr = WM8731_REG_ACTIVE_CTRL;
    cmd = _WM8731_ACTIVATE;
    addr = addr << 1;
    addr = addr|((cmd >> 8 )) & 0x01;
    cmd = cmd&0xFF;    
    i2c.start();
    i2c.write( WM8731_ADDRESS );//WM8731_REG_SAMPLING_CTRL, _WM8731_SAMPLING
    i2c.write( addr  );
    i2c.write( cmd );//there is also a deactive version!!
    i2c.stop();
    
    
    
    }

int main() {
    FMT_STRUCT wav_format;
    char data[2];
    pc.printf("Beginning of program\n");
    data[0] = 0x0F;
    data[1] = 0x00;
    FILE *my_wav;
    //my_wav = fopen("/sd/mydir/gp40.wav", "rb");//i think that it is "w" for write, "r"  for read.    
    my_wav = fopen("/sd/mydir/gp40_48K.wav", "rb");//i think that it is "w" for write, "r"  for read.    
    fseek(my_wav, 20, SEEK_SET); // set pointer to byte 20
    fread(&AudioFormat, 2, 1, my_wav); // check file is PCM
    if (AudioFormat==0x01) {
    printf("Wav file is PCM data\n\r");
    }
    else {
    printf("Wav file is not PCM data\n\r");
    }
    
    fseek  (my_wav,20,SEEK_SET);
    fread(&wav_format,sizeof(wav_format),1,my_wav);
    printf("%d  block align\n",wav_format.block_align);
    printf("  %d channels\n",wav_format.num_channels);
    
    
    fseek(my_wav, 36, SEEK_SET);
    fread(&wav_data.subchunk2_ID,4,1,my_wav);
    fseek(my_wav, 40, SEEK_SET);
    fread(&wav_data.subchunk2_size,4,1,my_wav);
    printf("DATA chunck\n");
    printf("  %d subchunk 2 ID\n",wav_data.subchunk2_ID);
    printf("  %d subchunk 2 size\n",wav_data.subchunk2_size);
    
    

    


    i2c.frequency(100000);
    long j = 0;
    
    printf("set up the codec\n\r");
    wm8731_configTEST();
    //i2s audio data transfer code??
    i2s.stereomono(I2S_STEREO);
    i2s.masterslave(I2S_MASTER);//MASTER definitely works!
    i2s.frequency(sample_freq);
    int yes = i2s.setup_ok();
    pc.printf("Setup went ok?: %d\n", yes);//0  = ack, 1 = Nack*/
    printf("can we get to this point?   1\n\r");
    led3 = 1;
    //myled = 1;
    led2 = 1;
    printf("can we get to this point?   2\n\r");

    myled = 1;
    i2s.start();
    //while (1) {
    fread(&wav_format,sizeof(wav_format),1,my_wav);
    printf("wav_format %d\n\r",wav_format);

            
    fseek(my_wav,20,SEEK_SET);
    fread(&wav_format,sizeof(wav_format),1,my_wav);
    fseek(my_wav,36,SEEK_SET);
    fread(&wav_data,sizeof(wav_data),1,my_wav);
    num_slices = wav_data.subchunk2_size/wav_format.block_align;
    printf("wav_data.subchunk2_size: %d\n\r",wav_data.subchunk2_size);
    printf("wav_format.block_align: %d\n\r",wav_format.block_align);
    printf("num_slices: %d\n\r",num_slices);
    printf("num_slices*wav_format.block_align %d\n\r",num_slices*wav_format.block_align);
    printf("wav_format.num_channels*wav_format.sig_bps/8: %d\n\r",wav_format.num_channels*wav_format.sig_bps/8);
              printf("chunk_size - sizeof(wav_format) %d\n\r",wav_data.subchunk2_size-sizeof(wav_format));
    printf("sizeof(wav_format): %d\n\r",sizeof(wav_format));
    //sampletick.attach(&isr,1/96000);
    //while(!feof(my_wav)){
    //while(1){
        //if (wav_data.subchunk2_size > sizeof(wav_format)){
          //fseek(my_wav,wav_data.subchunk2_size-sizeof(wav_format),SEEK_CUR);
        /*if(wav_data.subchunk2_size > (num_slices*wav_format.block_align)){
          fseek(my_wav,wav_data.subchunk2_size - (num_slices*wav_format.block_align),SEEK_CUR);
          printf("chunk_size - sizeof(wav_format) %d\n\r",wav_data.subchunk2_size-sizeof(wav_format));
          printf("sizeof(wav_format): %d\n\r",sizeof(wav_format));
        }
        else {
            
            break;
            }*/
            
    slice_buf=(char *)malloc(wav_format.block_align);
    for(int slice = 0; slice<num_slices; slice+=1)
    {       
      fread(&slice_buf,wav_format.block_align,1,my_wav);
      data_sptr=(int *)slice_buf;  
      //printf("data_sptr:%d\n\r",data_sptr);
      //printf("wav_format.num_channels: %d\n\r",wav_format.num_channels);
      //}
      slice_value = 0;

                //for (int channel=0;channel<wav_format.num_channels;channel++) 
               // {
                    int channel = 0;
                    //printf("channel: %d\n\r",channel);
                    //printf("wav_format.num_channels: %d\n\r",wav_format.num_channels);
                    int var = 1;//data_sptr[channel];
                    printf("var: %d\n\r", var);
                    //slice_value+=data_sptr[channel];
                    //printf("slice_value %d\n\r",slice_value);
                    //printf("data_sptr[channel] %d\n\r",data_sptr[channel] );
                    //slice_value = 21;//
                    //malloc(sizeof(data_sptr[channel]));
                    //printf("SIZEOF DATASPTR %d:\n\r",sizeof(data_sptr[channel]));
                    //newvar = data_sptr[channel];
                    //printf("newvar %d\n\r",newvar);
                    channel = channel + 1;
                    newvar = data_sptr[channel];
                    //printf("newvar %d\n\r",newvar);
                    //printf("channel: %d\n\r",channel);
                    //slice_value+=data_sptr[channel];
                  
                    //printf("did it get to this point\n\r");
                
                
                //printf("channel: %d  data %d\n\r",channel,data_sptr[channel]);
                //printf("slice_value: %d\n\r",slice_value);
                //}
      
     }
      
    
        sampletick.detach();
    i2s.stop();
    
    fclose(my_wav);
    printf("File is now closed.");
    return 0;
    }