This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LAUNCHXL-CC26X2R1: Play single tone using i2s and CC3200AUDBOOST module

Part Number: LAUNCHXL-CC26X2R1
Other Parts Discussed in Thread: CC3200AUDBOOST, CC3200

Hello all,

i'm using CC26x2 launchpad and CC3200AUDBOOST module togheter. What i want to achive is to play some melody using CC3200 audio board.

Sorry if my questions will be naive (or even stupid), but i'm totaly new to this topic (audio, i2s, etc).

So first what i did was run i2secho example from sdk 4.30 and it worked for me.

Now i want to just play single tone (1kHz sine wave). I tried to modify the example, but without success.

So generaly i created array with 1kHz sine wave to be played out. I used audio codec driver from example.

First i tried to use only i2s_startWrite() with one transaction but it didn't work.

So my idea was to use those lists (write, treatment and read) from example, and only modify "treatment buffers" before they will be send out. 
I did it like shown below:

       if(transactionToTreat != NULL){
            /*
             * Treatment:
             *   The higher the sampling frequency,
             *   the less time we have to process the data
             */

            // put sin 1khz to the buffer to be send out
            static size_t tmp = 0;
            int16_t* buf = transactionToTreat->bufPtr;

            for(size_t i = 0; i < BUFSIZE; i++){

                buf[i] = tone[tmp]; // put 1khz sine samples to the actual transaction buffer

                tmp++;
                if(tmp == tone_buffer_size_get()){

                    tmp = 0;
                }
            }


I simply copy values from my tone array which contains samples of 1kHz sine, to the transaction buffer that will be send out next.
But this doesnt work for me as well.

I've some questions about how to use i2s driver and audio codec.

1. How can i set up i2s or/and audio codec to only send out data. I dont need to read any data from mic.
I tried to pass "AudioCodec_MIC_NONE" to AudioCodec_config function but didn't saw any difference.

2. Have i always use both I2S_startRead() and I2S_startWrite()?

3. Is there any documentation for I2S driver? I couldnt find anything up to date.

4. How exactly works I2S driver? What will happen when i'll have only one transaction in list? Will it simply end transfer audio data?

Regrads,
mf

  • Hi,

    You may want to review the content of the file <SDK>\source\ti\drivers\I2S.h for documentation and code examples for the I2S driver.

    The code snippet you provided has at least one major error. The data is accessed by the I2S driver as 16-bit samples (or 24-bit, but the default is 16-bit). The size of the buffer in bytes is twice smaller than the size of the buffer in samples. As you are filling the buffer accessing the samples, you should not loop up to "BUFSIZE", rather "BUFSIZE/2". There is one more caveat, by default the I2S driver uses STEREO mode. In that case the two channels are interleaved.

    Here is my suggestion for looping in the buffer and filling it:

         // put sin 1khz to the buffer to be send out
         static size_t tmp = 0;
         int16_t* buf = transactionToTreat->bufPtr;
    
          for(size_t i = 0; i < BUFSIZE / 4; i++){
    
             buf[2*i]   = tone[tmp]; // put 1khz sine samples to the actual transaction buffer for channel 1
             buf[2*i+1] = tone[tmp]; // put 1khz sine samples to the actual transaction buffer for channel 2
     
             tmp++;
             if(tmp == tone_buffer_size_get()){
                tmp = 0;
             }
         }

    Last but not least, let me point you to our SimpleLink Audio Plugin. This plugin provides examples for audio streaming over different protocols (Sub-1GHz, BLE, Wifi).

    I hope this will help,

    Regards,

  • Hi, sorry for no response, but i had other stuff to do.

    I looked into I2S.h for documentation and it helped a bit.

    I did some modifications in my code.

    Codec and I2S driver initialization :

    status =  AudioCodec_config(AudioCodec_TI_3254, AudioCodec_16_BIT,
                                    SAMPLE_RATE, AudioCodec_MONO, AudioCodec_SPEAKER_ALL,
                                    AudioCodec_MIC_NONE);
    
        i2sParams.samplingFrequency =  SAMPLE_RATE;
        i2sParams.fixedBufferLength =  SineMonoSizeGet();
        i2sParams.writeCallback     =  writeCallbackFxn ;
        i2sParams.readCallback      =  readCallbackFxn ;
        i2sParams.errorCallback     =  errCallbackFxn;
        i2sHandle = I2S_open(CONFIG_I2S_0, &i2sParams);

    I am using single I2S_Transaction object, like below:

     List_clearList(&sineTransactionsList);
        I2S_Transaction_init(&sineTransaction);
        sineTransaction.bufPtr = SineMonoGet();
        sineTransaction.bufSize =   SineMonoSizeGet();
        List_put(&sineTransactionsList, (List_Elem*)&sineTransaction);
        List_tail(&sineTransactionsList)->next = List_head(&sineTransactionsList);
        List_head(&sineTransactionsList)->prev = List_tail(&sineTransactionsList);

    Then:

        I2S_setWriteQueueHead(i2sHandle, &sineTransaction);
        /* Start I2S streaming */
        I2S_startClocks(i2sHandle);
        //I2S_startRead(i2sHandle);
        I2S_startWrite(i2sHandle);

    What i get after these modifications is i can hear 1kHz sine beep in my headphones. Or at least something that sounds like this.
    But what is strange for me i can't see this sine wave on the oscilloscope. I tried to measure on jack connector or even directly on on codec's pins (hpl and hpr), and see only noise :<

    So i am not really sure if i am doing stuff properly...

    My sine buffer looks like this:

    static int16_t sinetable[] = { 0x0000 , 0x10b4 , 0x2120 , 0x30fb , 0x3fff , 0x4dea ,
                                   0x5a81 , 0x658b , 0x6ed8 , 0x763f , 0x7ba1 , 0x7ee5 ,
                                   0x7ffd , 0x7ee5 , 0x7ba1 , 0x76ef , 0x6ed8 , 0x658b ,
                                   0x5a81 , 0x4dea , 0x3fff , 0x30fb , 0x2120 , 0x10b4 ,
                                   0x0000 , 0xef4c , 0xdee0 , 0xcf06 , 0xc002 , 0xb216 ,
                                   0xa57f , 0x9a75 , 0x9128 , 0x89c1 , 0x845f , 0x811b ,
                                   0x8002 , 0x811b , 0x845f , 0x89c1 , 0x9128 , 0x9a76 ,
                                   0xa57f , 0xb216 , 0xc002 , 0xcf06 , 0xdee0 , 0xef4c
    };



    What i want to achive in general is to play some short melody (the idea is to work as ringbell). I've also tried to do this, but still without success...

    Do you have any ideas why i cannot see the sine on the oscilloscope? Or at least could you confirm that i am properly generating the sine?

    I also looked at the audio plugin, but had problems with compilation under ccs, so i left that topic.

    regards,

    mf

  • Hi,

    Mateusz Foks said:
    But what is strange for me i can't see this sine wave on the oscilloscope. I tried to measure on jack connector or even directly on on codec's pins (hpl and hpr), and see only noise :<

    The output signal is always very weak(we are talking about a hundreds of mV). But if you manage to hear something then it is promising.

    Mateusz Foks said:
    I also looked at the audio plugin, but had problems with compilation under ccs, so i left that topic.

    Make sure you are using the proper SDK (3_30)

    Regards,

  • Clément said:
    The output signal is always very weak(we are talking about a hundreds of mV).



    I'm aware of that, but i saw literally nothing...

    But assuming, that i'm correctly generating the sine wave. I still have problem with playing simple melody.

    How should look samples? Are there any special requirements (eg. little endian / big endian)?

    I think this is possible, that my problem lies in samples preparation.
    I downloaded some example audio file in wav format (coded in pcm) - 16 bit , 16khz sampling rate. Then I converted this file into c array using this program:

    http://colinjs.com/wavtocodeV1_0/wavtocode.htm

    I tried to send this to the codec with one transaction (one big buffer). But this doesn't worked.
    Should i divide data into more smaller transactions?

    Maybe could you provide me some sources, which explains how to properly prepare data to be send to the codec? I couldn't find anything valueable.

    regards,

    mf

  • Hi,

    You should review the driver's documentation - it states that you should at least have two buffers if I remember correctly.

    CC26xx devices are little endian. I would recommend to use a logic analyzer to examine the I2S signals and assess if you have the expected output.

    Best regards,