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.

CCS/CC1310: I2S on a CC1310

Part Number: CC1310
Other Parts Discussed in Thread: SYSBIOS,

Tool/software: Code Composer Studio

I am struggling to get the I2S working on my hardware. I am trying to use an example called I2S_init.  In the code it includes "static ti_sysbios_family_arm_m3_Hwi_Struct hwiStruct" Where do i find that?

I have download several other examples, but could really use some help with I2S. 

My application is to receive audio date via the 900mhz link, convert it ti I2S to load it into a DAC for my decode. 

TI could sure add more documentation on I2S. I have tried to use I2S.h, but need more help. The example I2s_init does not use I2S.c, but writes directly to registers. That's ok with me, but i have searched for the file above and can not find it.

  • Hi Larry,

    I don't believe there are any examples of I2S for the CC1310. I would recommend referencing the CC32xx I2S example/implementation for guidance on how to use the driver. http://dev.ti.com/tirex/explore/node?node=ALTgydjNS.parnl9AjM1Vw__fc2e6sr__LATEST 

    Thanks,

    Alexis

  • I have looked at the I2S echo, program. 

    You did not tell me where i can find "ti_sysbios_family_arm_m3_Hwi_Struct hwiStruct" This is referenced in I2S. Init and i can not find out how to download it. I have searched, but can not find out. 

  • I looked at the I2SECHO program again for the CC13x2 device. and was able to import it and compile it.  I could not run it because i did not have that launchpad. However, in looking at the I2S functions that w are describe in Sinplelink)CC13x1_CC26x2_sdk_3_10_00_53/source/ti/I2S.h file the I2S function is totally different then the I2S defined in the Simplelink for the CC1310. The I2S.h  showes an streaming example  ti_drivers_i2s_example_Streaming. Will that code also work for the CC1310 device? It looks like it has all the features. i need. 

    The code in simplelink for the CC1310 only used DMA to send data to the I2S port. 

  • Hi Larry,

    I haven't tried this, but yes you should be able to port it and make it backwards compatible. 

    Thanks,

    Alexis

  • I have spent many hours trying to get the I2S function on the CC1310.

    I came across the following in “C:\ti\simplelink_cc13x0_sdk_3_20_00_23\source\ti\drivers\I2S.h”

    The code is shown below:

     

    This is a Shot of the I2S signals: Here 16 words are being sent out with every other word being the same to write to a D/A.

     

     

    I have both the PlayAndStop and the RepeatMode totally functional. The Repeat mode did need some correction in the write ISR, adding the I2s_init() and making the end while like the while in PlayandStop. Compareit to Playand stop and make it the same.

     

    Somebody at TI could have saved me a lot of time if they had refered this code to me before!

     

    * @li @ref ti_drivers_I2S_Example_PlayAndStop "Play and Stop"

    * @li @ref ti_drivers_I2S_Example_Streaming "Streaming"

    * @li @ref ti_drivers_I2S_Example_RepeatMode "Repeat"

    *

    * <hr>

    * @anchor ti_drivers_I2S_Example_PlayAndStop

    * ### Mode Play and Stop #

    * The following example shows how to simultaneously receive and send out a given amount of data.

    *

    * <hr>

    * @anchor ti_drivers_I2S_Example_PlayAndStop_Code

    * @code

    * static I2S_Handle i2sHandle;

    * static I2S_Config i2sConfig;

    *

    * static uint16_t readBuf1[500]; // the data read will end up in this buffer

    * static uint16_t readBuf2[500]; // the data read will end up in this buffer

    * static uint16_t readBuf3[500]; // the data read will end up in this buffer

    * static uint16_t writeBuf1[250] = {...some data...}; // this buffer will be sent out

    * static uint16_t writeBuf2[250] = {...some data...}; // this buffer will be sent out

    * static uint16_t writeBuf3[250] = {...some data...}; // this buffer will be sent out

    *

    * static I2S_Transaction i2sRead1;

    * static I2S_Transaction i2sRead2;

    * static I2S_Transaction i2sRead3;

    * static I2S_Transaction i2sWrite1;

    * static I2S_Transaction i2sWrite2;

    * static I2S_Transaction i2sWrite3;

    *

    * List_List i2sReadList;

    * List_List i2sWriteList;

    *

    * static volatile bool readStopped = (bool)true;

    * static volatile bool writeStopped = (bool)true;

    *

    * static void writeCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {

    *

    *     if(status & I2S_ALL_TRANSACTIONS_SUCCESS){

    *

    *         // Note: Here we do not queue new transfers or set a new queue-head.

    *         // The driver will stop sending out data on its own.

    *         writeStopped = (bool)true;

    *     }

    * }

    *

    * static void readCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {

    *

    *      if(status & I2S_ALL_TRANSACTIONS_SUCCESS){

    *

    *         // Note: Here we do not queue new transfers or set a new queue-head.

    *         // The driver will stop receiving data on its own.

    *         readStopped = (bool)true;

    *     }

    * }

    *

    * static void errCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {

    *

    *     // Handle the I2S error

    * }

    *

    * void *modePlayAndStopThread(void *arg0)

    * {

    *     I2S_Params i2sParams;

    *

    *     I2S_init();

    *

    *    // Initialize I2S opening parameters

    *     I2S_Params_init(&i2sParams);

    *     i2sParams.fixedBufferLength     = 500; // fixedBufferLength is the greatest common

    *                                             // divisor of all the different buffers

    *                                             // (here buffers' size are 500 and 1000 bytes)

    *     i2sParams.writeCallback         = writeCallbackFxn ;

    *     i2sParams.readCallback         = readCallbackFxn ;

    *     i2sParams.errorCallback        = errCallbackFxn;

    *

    *     i2sHandle = I2S_open(Board_I2S0, &i2sParams);

    *

    *     // Initialize the read-transactions

    *     I2S_Transaction_init(&i2sRead1);

    *     I2S_Transaction_init(&i2sRead2);

    *     I2S_Transaction_init(&i2sRead3);

    *    i2sRead1.bufPtr           = readBuf1;

    *     i2sRead2.bufPtr           = readBuf2;

    *     i2sRead3.bufPtr           = readBuf3;

    *     i2sRead1.bufSize           = sizeof(readBuf1);

    *     i2sRead2.bufSize           = sizeof(readBuf2);

    *     i2sRead3.bufSize           = sizeof(readBuf3);

    *     List_put(&i2sReadList, (List_Elem*)&i2sRead1);

    *     List_put(&i2sReadList, (List_Elem*)&i2sRead2);

    *     List_put(&i2sReadList, (List_Elem*)&i2sRead3);

    *

    *     I2S_setReadQueueHead(i2sHandle, &i2sRead1);

    *

    *     // Initialize the write-transactions

    *     I2S_Transaction_init(&i2sWrite1);

    *     I2S_Transaction_init(&i2sWrite2);

    *     I2S_Transaction_init(&i2sWrite3);

    *     i2sWrite1.bufPtr           = writeBuf1;

    *     i2sWrite2.bufPtr          = writeBuf2;

    *     i2sWrite3.bufPtr           = writeBuf3;

    *     i2sWrite1.bufSize         = sizeof(writeBuf1);

    *     i2sWrite2.bufSize         = sizeof(writeBuf2);

    *     i2sWrite3.bufSize         = sizeof(writeBuf3);

    *     List_put(&i2sWriteList, (List_Elem*)&i2sWrite1);

    *     List_put(&i2sWriteList, (List_Elem*)&i2sWrite2);

    *     List_put(&i2sWriteList, (List_Elem*)&i2sWrite3);

    *

    *     I2S_setWriteQueueHead(i2sHandle, &i2sWrite1);

    *

    *     I2S_startClocks(i2sHandle);

    *     I2S_startWrite(i2sHandle);

    *     I2S_startRead(i2sHandle);

    *

    *     readStopped = (bool)false;

    *     writeStopped = (bool)false;

    *

    *     while(1) {

    *

    *         if(readStopped && writeStopped) {

    *             I2S_stopClocks(i2sHandle);

    *            I2S_close(i2sHandle);

    *             while(1);

    *         }

    *     }

    * }

    * @endcode

    *

    * \note If you desire to put only one transaction in the queue, fixedBufferLength must be inferior to half the length (in bytes) of the buffer to transfer.

    *

    * <hr>

    * @anchor ti_drivers_I2S_Example_Streaming

    * ### Writing Data in Continuous Streaming Mode #

    * The following example shows how to read and write data in streaming mode.

    * A dummy treatment of the data is also done.

    * This example is not complete (semaphore and tasks creation are not shown)

    *

    * <hr>

    * @anchor ti_drivers_I2S_Example_Streaming_Code

    * @code

    * static I2S_Handle i2sHandle;

    * static I2S_Config i2sConfig;

    *

    * // These buffers will successively be written, treated and sent out

    * static uint16_t readBuf1[500];

    * static uint16_t readBuf2[500];

    * static uint16_t readBuf3[500];

    * static uint16_t readBuf4[500];

    * static uint16_t writeBuf1[500]={0};

    * static uint16_t writeBuf2[500]={0};

    * static uint16_t writeBuf3[500]={0};

    * static uint16_t writeBuf4[500]={0};

    *

    * // These transactions will successively be part of the

    * // i2sReadList, the treatmentList and the i2sWriteList

    * static I2S_Transaction i2sRead1;

    * static I2S_Transaction i2sRead2;

    * static I2S_Transaction i2sRead3;

    * static I2S_Transaction i2sRead4;

    * static I2S_Transaction i2sWrite1;

    * static I2S_Transaction i2sWrite2;

    * static I2S_Transaction i2sWrite3;

    * static I2S_Transaction i2sWrite4;

    *

    * List_List i2sReadList;

    * List_List treatmentList;

    * List_List i2sWriteList;

    *

    * static void writeCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {

    *

    *     // We must remove the previous transaction (the current one is not over)

    *     I2S_Transaction *transactionFinished = (I2S_Transaction*)List_prev(&transactionPtr->queueElement);

    *

    *     if(transactionFinished != NULL){

    *         // Remove the finished transaction from the write queue

    *         List_remove(&i2sWriteList, (List_Elem*)transactionFinished);

    *

    *         // This transaction must now feed the read queue (we do not need anymore the data of this transaction)

    *         transactionFinished->queueElement.next = NULL;

    *         List_put(&i2sReadList, (List_Elem*)transactionFinished);

    *

    *         // We need to queue a new transaction: let's take one in the treatment queue

    *         I2S_Transaction *newTransaction = (I2S_Transaction*)List_head(&treatmentList);

    *         if(newTransaction != NULL){

    *            List_remove(&treatmentList, (List_Elem*)newTransaction);

    *             newTransaction->queueElement.next = NULL;

    *             List_put(&i2sWriteList, (List_Elem*)newTransaction);

    *         }

    *     }

    * }

    *

    * static void readCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {

    *

    *     // We must remove the previous transaction (the current one is not over)

    *     I2S_Transaction *transactionFinished = (I2S_Transaction*)List_prev(&transactionPtr->queueElement);

    *

    *     if(transactionFinished != NULL){

    *         // The finished transaction contains data that must be treated

    *         List_remove(&i2sReadList, (List_Elem*)transactionFinished);

    *         transactionFinished->queueElement.next = NULL;

    *         List_put(&treatmentList, (List_Elem*)transactionFinished);

    *

    *         // Start the treatment of the data

    *         Semaphore_post(dataReadyForTreatment);

    *

    *         // We do not need to queue transaction here: writeCallbackFxn takes care of this :)

    *     }

    * }

    *

    * static void errCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {

    *

    *     // Handle the I2S error

    * }

    *

    * void *myTreatmentThread(void *arg0){

    *

    *     int k;

    *

    *      while(1) {

    *         Semaphore_pend(dataReadyForTreatment, BIOS_WAIT_FOREVER);

    *

    *         if(lastAchievedReadTransaction != NULL) {

    *

    *             // Need a critical section to be sure to have corresponding bufPtr and bufSize

    *             uintptr_t key = HwiP_disable();

    *             uint16_t *buf = lastAchievedReadTransaction->bufPtr;

    *             uint16_t bufLength = lastAchievedReadTransaction->bufSize / sizeof(uint16_t);

    *             HwiP_restore(key);

    *

    *             // My dummy data treatment...

    *             for(k=0; k<bufLength; k++) {buf[k] --;}

    *             for(k=0; k<bufLength; k++) {buf[k] ++;}

    *         }

    *     }

    * }

    *

    * void *echoExampleThread(void *arg0)

    * {

    *     I2S_Params i2sParams;

    *

    *     I2S_init();

    *

    *     // Initialize the treatmentList (this list is initially empty)

    *     List_clearList(&treatmentList);

    *

    *     //Initialize I2S opening parameters

    *     I2S_Params_init(&i2sParams);

    *     i2sParams.fixedBufferLength     = 1000;

    *     i2sParams.writeCallback         = writeCallbackFxn ;

    *     i2sParams.readCallback         = readCallbackFxn ;

    *     i2sParams.errorCallback         = errCallbackFxn;

    *

    *     i2sHandle = I2S_open(Board_I2S0, &i2sParams);

    *

    *     // Initialize the read-transactions

    *     I2S_Transaction_init(&i2sRead1);

    *     I2S_Transaction_init(&i2sRead2);

    *     I2S_Transaction_init(&i2sRead3);

    *     I2S_Transaction_init(&i2sRead4);

    *     i2sRead1.bufPtr           = readBuf1;

    *     i2sRead2.bufPtr           = readBuf2;

    *     i2sRead3.bufPtr           = readBuf3;

    *     i2sRead4.bufPtr           = readBuf4;

    *     i2sRead1.bufSize           = sizeof(readBuf1);

    *     i2sRead2.bufSize           = sizeof(readBuf2);

    *     i2sRead3.bufSize           = sizeof(readBuf3);

    *     i2sRead4.bufSize           = sizeof(readBuf4);

    *     List_clearList(&i2sReadList);

    *     List_put(&i2sReadList, (List_Elem*)&i2sRead1);

    *     List_put(&i2sReadList, (List_Elem*)&i2sRead2);

    *     List_put(&i2sReadList, (List_Elem*)&i2sRead3);

    *     List_put(&i2sReadList, (List_Elem*)&i2sRead4);

    *

    *     I2S_setReadQueueHead(i2sHandle, &i2sRead1);

    *

    *     // Initialize the write-transactions

    *     I2S_Transaction_init(&i2sWrite1);

    *     I2S_Transaction_init(&i2sWrite2);

    *     I2S_Transaction_init(&i2sWrite3);

    *     I2S_Transaction_init(&i2sWrite4);

    *     i2sWrite1.bufPtr           = writeBuf1;

    *     i2sWrite2.bufPtr           = writeBuf2;

    *     i2sWrite3.bufPtr           = writeBuf3;

    *    i2sWrite4.bufPtr           = writeBuf4;

    *     i2sWrite1.bufSize         = sizeof(writeBuf1);

    *     i2sWrite2.bufSize         = sizeof(writeBuf2);

    *     i2sWrite3.bufSize         = sizeof(writeBuf3);

    *     i2sWrite4.bufSize         = sizeof(writeBuf4);

    *     List_clearList(&i2sWriteList);

    *     List_put(&i2sWriteList, (List_Elem*)&i2sWrite1);

    *     List_put(&i2sWriteList, (List_Elem*)&i2sWrite2);

    *     List_put(&i2sWriteList, (List_Elem*)&i2sWrite3);

    *     List_put(&i2sWriteList, (List_Elem*)&i2sWrite4);

    *

    *     I2S_setWriteQueueHead(i2sHandle, &i2sWrite1);

    *

    *     I2S_startClocks(i2sHandle);

    *     I2S_startWrite(i2sHandle);

    *     I2S_startRead(i2sHandle);

    *

    *     while(1);

    * }

    * @endcode

    *

    * <hr>

    * @anchor ti_drivers_I2S_Example_RepeatMode

    * ### Writing Data in repeat Mode #

    * The following example shows how to read and write data in repeat mode.

    * The same buffers are continuously written and send out while the driver is not stopped.

    * Here, we decide to only stop sending out after an arbitrary number of sending.

    *

    * <hr>

    * @anchor ti_drivers_I2S_Example_RepeatMode_Code

    * @code

    * static I2S_Handle i2sHandle;

    * static I2S_Config i2sConfig;

    * static I2SCC26XX_Object i2sObject;

    *

    * // This buffer will be continuously re-written

    * static uint16_t readBuf[500];

    * // This data will be continuously sent out

    * static uint16_t writeBuf[500] = {...some cool data...};

    *

    * static I2S_Transaction i2sRead;

    * static I2S_Transaction i2sWrite;

    *

    * List_List i2sReadList;

    * List_List i2sWriteList;

    *

    * static volatile bool writeFinished = (bool)false;

    * static void writeCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {

    *

    *     // Nothing to do here: the buffer(s) are queued in a ring list, the transfers are

    *     // executed without any action from the application.

    *

    *     // We must consider the previous transaction (ok, when you have only one transaction it's the same)

    *     I2S_Transaction *transactionFinished = (I2S_Transaction*)List_prev(&transactionPtr->queueElement);

    *

    *     if(transactionFinished != NULL){

    *         // After an arbitrary number of completion of the transaction, we will stop writting

    *         if(transactionFinished->numberOfCompletions >= 10) {

    *

    *             // Note: You cannot use I2S_stopRead() / I2S_stopWrite() in the callback.

    *             // The execution of these functions is potentially blocking and can mess up the

    *             // system.

    *

    *              writeFinished = (bool)true;

    *         }

    *     }

    * }

    *

    * static void readCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {

    *     // Nothing to do here: the buffer(s) are queued in a ring list, the transfers are

    *     // executed without any action from the application.

    * }

    *

    * static void errCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {

    *

    *     // Handle the I2S error

    * }

    *

    * void *modeRepeat(void *arg0)

    * {

    *     I2S_Params i2sParams;

    *

    *     // Initialize I2S opening parameters

    *     I2S_Params_init(&i2sParams);

    *     i2sParams.fixedBufferLength     = 1000; // No problem here: the driver consider

    *                                              // the list as an infinite list.

    *     i2sParams.writeCallback         = writeCallbackFxn ;

    *     i2sParams.readCallback         = readCallbackFxn ;

    *     i2sParams.errorCallback         = errCallbackFxn;

    *

    *     i2sHandle = I2S_open(Board_I2S0, &i2sParams);

    *

    *     // Initialize the read-transactions

    *     I2S_Transaction_init(&i2sRead);

    *     i2sRead.bufPtr           = readBuf;

    *     i2sRead.bufSize           = sizeof(readBuf);

    *     List_put(&i2sReadList, (List_Elem*)&i2sRead);

    *     List_tail(&i2sReadList)->next = List_head(&i2sReadList);// Read buffers are queued in a ring-list

    *     List_head(&i2sReadList)->prev = List_tail(&i2sReadList);

    *

    *     I2S_setReadQueueHead(i2sHandle, &i2sRead);

    *

    *     // Initialize the write-transactions

    *     I2S_Transaction_init(&i2sWrite);

    *     i2sWrite.bufPtr           = writeBuf;

    *     i2sWrite.bufSize         = sizeof(writeBuf);

    *     List_put(&i2sWriteList, (List_Elem*)&i2sWrite);

    *     List_tail(&i2sWriteList)->next = List_head(&i2sWriteList); // Write buffers are queued in a ring-list

    *     List_head(&i2sWriteList)->prev = List_tail(&i2sWriteList);

    *

    *     I2S_setWriteQueueHead(i2sHandle, &i2sWrite);

    *

    *     I2S_startClocks(i2sHandle);

    *     I2S_startWrite(i2sHandle);

    *     I2S_startRead(i2sHandle);

    *

    *     while(1){

    *

    *         if(writeFinished){

    *             writeFinished = (bool)false;

    *             I2S_stopWrite(i2sHandle);

    *         }

    *     }

    * }

    * @endcode

    *

    * @note In the case of circular lists, there is no problem to put only

    * one buffer in the queue.

    *

    * <hr>