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.

USBstick TMS320C5515 I2S bus peripheral interrupt doesn't work

Other Parts Discussed in Thread: TMS320C5515

I am trying to use the codec on the USBstick to develop DSP code for a test instrumentation product. I must write my own hardware drivers for the C5515 because of how the product will work. I have been able to figure out all the problems myself until I tried to make an interrupt happen when new ADC data is ready. While my logic analyzer shows that the I2S Frame Sync and I2S Bit Clock are present, and are sourced by the codec, I don't get interrupts. As you can see, interrupts should only toggle the DSP external flag for now, but that does not happen, so no interrupts are happening. I have attached my main.c and StkVectors.asm, but not my StkHardware.c (init and drivers) or StkLink.cmd for now; I can provide them later if that helps. Everything compiles together OK.

/********
 * main.c
 ********/

#include "StkHardware.h"

long AdcLData, AdcRData, DacLData, DacRData;

void main(void)
{

PowerUpInit();

EnableInts();

while (1);

return;

}	/********** End main ******************/

interrupt void I2SDacIsr(void)
{	/* Interrupt Service Routine for I2S0 DACs is Priority 7 */
	/* Interrupt Service Routine for I2S2 DACs is Priority 21 */
	/* NOTE: no parameters may be passed into or returned from an
	 *	interrupt service routine.  Use Global variables */
	volatile unsigned delay;

	asm(" bit(ST1, #13) = #1");	/* Set External Flag, XF pin high, LED on */

/* This loop should delay ( 7 + ( 7 * 6)) / 98304000 = 0.0000005 seconds */
	for ( delay = 6 ; delay > 0 ; delay-- ){};	/* wait 0.5 microseconds */

	asm(" bit(ST1, #13) = #0");	/* Clear External Flag, XF pin low, LED off */

	return;
}	/********** END I2S0DacIsr() **********************************************/


interrupt void I2SAdcIsr(void)
{	/* Interrupt Service Routine for I2S2 ADCs is Priority 10 */
	/* Interrupt Service Routine for I2S0 ADCs is Priority 22 */
	/* NOTE: no parameters may be passed into or returned from an
	 *	interrupt service routine.  Use Global variables */
	volatile unsigned delay;

	asm(" bit(ST1, #13) = #1");	/* Set External Flag, XF pin high, LED on */

/* This loop should delay ( 7 + ( 7 * 28)) / 98304000 = 0.0000021 seconds */
	for ( delay = 28 ; delay > 0 ; delay-- ){};	/* wait 2.1 microseconds */

	asm(" bit(ST1, #13) = #0");	/* Clear External Flag, XF pin low, LED off */

	return;
}	/********** END I2S0AdcIsr() **********/
6787.StkVectors.asm

  • Hi Emeric,

    Are you enabling all interrupts? You do not show the code for the function EnableInts(). Can you attach that and also the .cmd file?

    The below code shows setting the RTC interrupt:
        
        asm("    @#IFR0_L = #0xffff || mmap() ");
        asm("    @#IER0_L = #0x0000 || mmap() ");
        asm("    @#IFR1_L = #0xffff || mmap() ");
        asm("    @#IER1_L = #0x0004 || mmap() ");
        asm(" bit(ST1,#11) = #0 "); // GLOBAL INTERRUPT ENABLE

    The Chip Support Library uses different syntax to enable interrupts, but you could refer also to c55xx_csl_3.00\ccs_v4.0_examples\i2s\CSL_I2S_INTCExample

    Download the Chip Support Library from http://www.ti.com/tool/sprc133

    Hope this helps,
    Mark

  • Hi Mark,

    Thanks for your response. I thought nobody would answer. I am trying to get this to work without using the CSL, if that is possible. Here are sections from my code.


    My StkHardware.h header file includes these definitions:

    /******* Define TMS320C5515 memory mapped interrupt & status registers ********
    *
    ****** see spru371f.pdf Table 2-2 for addresses, as noted for descriptions ***/

    #define IER0 *(volatile unsigned int *) 0x0000 /* 2.8.3 - Interrupt Enable */
    #define IER1 *(volatile unsigned int *) 0x0045 /* 2.8.3 - Interrupt Enable */
    #define IFR0 *(volatile unsigned int *) 0x0001 /* 2.8.2 - Interrupt Flag */
    #define IFR1 *(volatile unsigned int *) 0x0046 /* 2.8.2 - Interrupt Flag */

    I also have this in there with a lot of other definitions:

    #define I2SINTFL *(volatile ioport unsigned int*)(0x2810) /* Section 1.3.7 */
    #define I2SINTMASK *(volatile ioport unsigned int*)(0x2814) /* Section 1.3.8 */


    Here is the last part of my PowerUpInit() function in my StkHardware.c file:


    /* Initialize processor interrupts ********************************************
    *
    * in IER0, IE5 (0x0020) is the I2S0 transmit interrupt enable bit (codec DACs)
    * in IER0, IE7 (0x0080) is the I2S0 receive interrupt enable bit (codec ADCs)
    * in IFR0, the corresponding bits are the flags for these interrupts
    *
    ********see spru371f.pdf Section 2.8 for register descriptions ***************/

    IER0 = 0x00A0; /* Enable IE5 and IE7 interrupts only*/
    IER1 = 0x0; /* Disable these peripheral interrupts */

    asm(" bit(ST1, #11) = #0"); /* Enable Global Interrupts in CPU
    * bit 11 is INTM - global int mask */

    /* Global interrupts are now enabled, along with the second level prioritized
    * interrupts but third level individual peripheral interrupts are not
    * enabled here. They are enabled elsewhere, No interrupts will occur
    * until they are enabled.
    *
    ***** End of initialize processor interrupts ********************************/

    Init3204Codec();

    SetBaudrate(0x0280); /* Reset the UART and set baudrate
    * 0x0A00 is 2400 baud, 0x0280 is 9600 baud */

    return 0;

    } /***** END PowerUpInit() **********/


    I expect to get the flag LED on the USBstick to change state once I call this function:

    int EnableInts(void)
    { /* Enable ADC and DAC interrupts on I2S */

    int IntFlags;

    IntFlags = I2SINTFL; /* I2S Interrupt Flag Register - Section 1.3.7 */
    /* READ ONLY register - reading clears all flags */
    I2SINTMASK = 0x0028; /* I2S Interrupt Mask Register - Section 1.3.8 */
    /* Enable I2S2 interrupts
    * [5] XMITST - Enable TX data interrupt
    * [3] RCVST - Enable Rx data interrupt */
    return IntFlags;

    } /*********** END EnableInts() ************/


    I hope I am doing something obviously stupid, because if I am not, I really do not understand something here.

    Thanks in advance for your help.

    Emeric

  • Hi Emeric,

    First, sorry for the delay. I have reviewed your last post and code.

    If you can use the CSL, it makes support easier.

    There are non-CSL based examples you can refer to like C5515 eZdsp Audio Filter Demo from http://code.google.com/p/c5505-ezdsp/

    See also the Spectrum Digital I2S example for the C5515 eZdsp (Click on Test Code): http://support.spectrumdigital.com/boards/usbstk5515/reva/

    Reviewing your post and code...

    IER0 & I2SINTMASK are set correctly for Stereo I2S0 TX/RX interrupts.

    *** Check EBSR - SP0MODE... If SP0MODE = 01, PROG1 bit supports I2S0 receive interrupts and PROG0 transmit interrupts.
    SP0MODE resets to 00 - muxing MMC/SD0 signals to the device pins instead of I2S0 signals...

    If using DMA, make sure MPORT not idle in ICR (I dont see DMA used).

    vectors.asm looks correct, but make sure the vectors.asm file is included in the .cmd file correctly so that the ISR is mapped to that interrupt (from Audio Filter Demo):
        SECTIONS
        {
            vectors (NOLOAD)
            .bss        : > DARAM /*, fill = 0 */
            vector      : > DARAM      ALIGN = 256
            .stack      : > DARAM  
        ...

    Init3204Codec(); is not shown... Also I don't see any I2S configuration. You have to initialize its formatting, clocking, and word lengths, etc. What device is the I2S Master and what are the clock generator settings?

    Study the Audio Filter Demo code - it uses DMA and DMA interrupts instead of I2S interrupts...

    See also this code excerpt that tests I2S0 TX externally looped back to I2S0 RX - I2S0_RX and I2S0_TX signals must be exteranlly shorted.

    /*  ============================================================================
     *   Copyright (c) Texas Instruments Inc 2002, 2003, 2004, 2005, 2008
     *
     *   Use of this software is controlled by the terms and conditions found in the
     *   license agreement under which this software has been supplied.
     *  ============================================================================
     */
    
    /** @file csl_i2s_IntcExample.c
     *
     *  @brief Test code to verify the CSL I2S functionality in Interrupt mode
     *
     *
     * \page    page6  I2S EXAMPLE DOCUMENTATION
     *
     * \section I2S3   I2S EXAMPLE3 - INTERRUPT MODE TEST
     *
     * \subsection I2S3x    TEST DESCRIPTION:
     *		This test verifies the operation of CSL I2S module in interrupt mode.
     * I2S module on C5505/C5515 DSP is used to exchange the audio data between
     * the audio codec and DSP.
     *
     * Testing of the I2S with the audio codec is not possible as codec is not
     * part of the CSL package. This test verifies the I2S operation in loopback
     * mode. In loopback mode of operation data written to the I2S data transmit
     * registers will be transmitted to the I2S data receive registers. CSL INTC
     * module should be configured and I2S ISR should be registered before starting
     * the data transfer. Separate ISRs are registered for I2S Tx and Rx. Interrupts
     * are used to check the Tx/Rx status of the I2S. I2S is configured to master
     * mode,stereo, 16bit data length and to loop back mode. When the I2S data
     * transfer is enabled I2S starts generating the Tx interrupts. Data is written
     * to the I2S Tx registers in the ISR 'i2s_txIsr'. As the I2S is configured in
     * loopback mode when the data is written to Tx register it will be transmitted
     * to Rx register and Rx interrupt will be generated. Data will be read from the
     * I2S Rx registers in the ISR 'i2s_rxIsr'.I2S write and read buffers are
     * compared for the data verification.
     *
     * NOTE: THIS TEST HAS BEEN DEVELOPED TO WORK WITH CHIP VERSIONS C5505 AND
     * C5515. MAKE SURE THAT PROPER CHIP VERSION MACRO IS DEFINED IN THE FILE
     * c55xx_csl\inc\csl_general.h.
     *
     * \subsection I2S3y    TEST PROCEDURE:
     *  @li Open the CCS and connect the target (C5505/C5515 EVM)
     *  @li Open the project "CSL_I2S_INTCExample_Out.pjt" and build it
     *  @li Load the program on to the target
     *  @li Set the PLL frequency to 12.288MHz
     *  @li Run the program and observe the test result
     *  @li Repeat the test at PLL frequencies 40, 60, 75 and 100MHz
     *  @li Repeat the test in Release mode
     *
     * \subsection I2S3z    TEST RESULT:
     *  @li All the CSL APIs should return success
     *  @li Read and write data buffer comparison should be successful.
     *
     *
     */
    
    /* ============================================================================
     * Revision History
     * ================
     * 05-Sep-2008 Created
     * ============================================================================
     */
    
    #include "csl_i2s.h"
    #include "csl_intc.h"
    #include <csl_general.h>
    #include <stdio.h>
    
    #define CSL_TEST_FAILED         (1)
    #define CSL_TEST_PASSED         (0)
    #define	CSL_I2S_BUF_LEN			(4)
    
    CSL_IrqDataObj  CSL_IrqData;
    Uint16 i2sIntcWriteBuff[CSL_I2S_BUF_LEN];
    Uint16 i2sIntcReadBuff[CSL_I2S_BUF_LEN];
    CSL_I2sHandle	i2sHandle;
    Uint16 writeCompete = 0;
    Uint16 readComplete = 0;
    extern void VECSTART(void);
    
    /*
    	This is ISR for the data transmission.
    	This function returns:
    	Void               -void
    */
    interrupt void i2s_rxIsr()
    {
    	Int16 			result;
    
    	IRQ_disable(PROG1_EVENT);
    	/** Read data from register and buffered					*/
    	result = I2S_read(i2sHandle, i2sIntcReadBuff, CSL_I2S_BUF_LEN);
    	if(result == CSL_SOK)
    	{
    		printf ("I2S Read Successful\n");
    		readComplete = 1;
    	}
    }
    
    /*
    	This is ISR for the data Receive.
    	This function returns:
    	Void               -void
    */
    interrupt void i2s_txIsr()
    {
    	Int16 			result;
    
    	IRQ_disable(PROG0_EVENT);
    
    	/** Write the buffer data to the registers					*/
    	result = I2S_write(i2sHandle, i2sIntcWriteBuff, CSL_I2S_BUF_LEN);
    	if(result == CSL_SOK)
    	{
    		printf ("I2S Write Successful\n");
    		writeCompete = 1;
    	}
    }
    
    
    /*
    	This is functionality Transmit  and
    	receive data with interrupt mode.
    	The data transmission and receive happen in stereo mode.
    
    	Function returns:
    	CSL_TEST_FAILED                -Failure
    	CSL_TEST_PASSED                -Success
    */
    
    Int16 i2s_IntcSample(void)
    {
    	Int16 			status = CSL_TEST_FAILED;
    	Int16 			result;
    	I2S_Config		hwConfig;
    	Uint16 			looper;
    	CSL_IRQ_Config 	config;
    
    	/* Initialize the read and write buffers					*/
    	for(looper=0; looper < CSL_I2S_BUF_LEN; looper++)
    	{
    		i2sIntcWriteBuff[looper] = 0x001 + looper;
    		i2sIntcReadBuff[looper]  = 0xffff;
    	}
    
    
    	/* Open the device with instance 0							*/
    	i2sHandle = I2S_open(I2S_INSTANCE0, I2S_INTERRUPT, I2S_CHAN_STEREO);
    
    
    	if(NULL == i2sHandle)
    	{
    		status = CSL_TEST_FAILED;
    		return (status);
    	}
    	else
    	{
    		printf ("I2S Module Instance Open Successful\n");
    	}
    
    	/* Set the value for the configure structure				*/
    	hwConfig.dataType 			= I2S_STEREO_ENABLE;
    	hwConfig.loopBackMode 		= I2S_LOOPBACK_ENABLE;
    	hwConfig.fsPol 				= I2S_FSPOL_LOW;
    	hwConfig.clkPol				= I2S_FALLING_EDGE;
    	hwConfig.datadelay			= I2S_DATADELAY_ONEBIT;
    	hwConfig.datapack			= I2S_DATAPACK_ENABLE;
    	hwConfig.signext			= I2S_SIGNEXT_DISABLE;
    	hwConfig.wordLen			= I2S_WORDLEN_16;
    	hwConfig.i2sMode			= I2S_MASTER;
    	hwConfig.clkDiv				= I2S_CLKDIV4;
    	hwConfig.fsDiv				= I2S_FSDIV32;
    	hwConfig.FError				= I2S_FSERROR_ENABLE;
    	hwConfig.OuError			= I2S_OUERROR_ENABLE;
    
    	/* Configure hardware registers							*/
    	result = I2S_setup(i2sHandle, &hwConfig);
    
    	if(result != CSL_SOK)
    	{
    		status = CSL_TEST_FAILED;
    		return (status);
    	}
    	else
    	{
    		printf ("I2S Module Configuration Successful\n");
    	}
    
    	/* Clear any pending interrupts */
    	IRQ_clearAll();
    
    	/* Disable all the peripheral interrupts */
    	IRQ_disableAll();
    
    	IRQ_setVecs((Uint32)(&VECSTART));
    	/* Configuring Interrupt */
    
        config.funcAddr = &i2s_txIsr;
    	IRQ_plug (PROG0_EVENT, config.funcAddr);
    	/* Enabling Interrupt */
    	IRQ_enable(PROG0_EVENT);
    
    	IRQ_globalEnable();
    
    	result = I2S_transEnable(i2sHandle, TRUE);
    	while(writeCompete != 1);
    	IRQ_globalDisable();
    	result = I2S_transEnable(i2sHandle, FALSE);
    
    	config.funcAddr = &i2s_rxIsr;
    	IRQ_plug (PROG1_EVENT, config.funcAddr);
    	/* Enabling Interrupt */
    	IRQ_enable(PROG1_EVENT);
    
    	IRQ_globalEnable();
    	result = I2S_transEnable(i2sHandle, TRUE);
    	while(readComplete != 1);
    	IRQ_globalDisable();
    	result = I2S_transEnable(i2sHandle, FALSE);
    
    	/* Reset the registers										*/
    	result = I2S_reset(i2sHandle);
    
    	if(result != CSL_SOK)
    	{
    		return (CSL_TEST_FAILED);
    	}
    	else
    	{
    		printf ("I2S Reset Successful\n");
    	}
    
    	/* Close the operation										*/
    	result = I2S_close(i2sHandle);
    
    	if(result != CSL_SOK)
    	{
    		status = CSL_TEST_FAILED;
    		return (status);
    	}
    	else
    	{
    		printf ("I2S Close Successful\n");
    	}
    
    	/* Clear any pending interrupts */
    	IRQ_clearAll();
    
    	/* Disable all the peripheral interrupts */
    	IRQ_disableAll();
    
    	/* Compare the read and write buffer						*/
    	for(looper=0; looper < CSL_I2S_BUF_LEN; looper++)
    	{
    		if(i2sIntcWriteBuff[looper] != i2sIntcReadBuff[looper])
    		{
    			printf("I2S Read & Write Buffers doesn't Match!!!\n");
    			status = CSL_TEST_FAILED;
    			return(status);
    		}
    	}
    
    	if(looper == CSL_I2S_BUF_LEN)
    	{
    		printf("I2S Read & Write Buffers Match!!!\n");
    	}
    
    	return (CSL_TEST_PASSED);
    }
    
    
    /*
     This is the main function to call sample program
    */
       /////INSTRUMENTATION FOR BATCH TESTING -- Part 1 --   
       /////  Define PaSs_StAtE variable for catching errors as program executes.
       /////  Define PaSs flag for holding final pass/fail result at program completion.
            volatile Int16 PaSs_StAtE = 0x0001; // Init to 1. Reset to 0 at any monitored execution error.
            volatile Int16 PaSs = 0x0000; // Init to 0.  Updated later with PaSs_StAtE when and if
       /////                                  program flow reaches expected exit point(s).
       /////
    void main(void)
    {
    	Int16    status;
    
    	printf("CSL I2S INTERRUPT MODE TEST!\n\n");
    
    	IRQ_globalDisable();
    	status = i2s_IntcSample();
    	if(status != CSL_TEST_PASSED)
    	{
    		printf("\nCSL I2S INTERRUPT MODE TEST FAILED!!\n\n");
       /////INSTRUMENTATION FOR BATCH TESTING -- Part 2 --   
       /////  Reseting PaSs_StAtE to 0 if error detected here.
            PaSs_StAtE = 0x0000; // Was intialized to 1 at declaration.
       /////
    	}
    	else
    	{
    		printf("\nCSL I2S INTERRUPT MODE TEST PASSED!!\n\n");
    	}
    
    	IRQ_globalDisable();
       /////INSTRUMENTATION FOR BATCH TESTING -- Part 3 -- 
       /////  At program exit, copy "PaSs_StAtE" into "PaSs".
            PaSs = PaSs_StAtE; //If flow gets here, override PaSs' initial 0 with 
       /////                   // pass/fail value determined during program execution.
       /////  Note:  Program should next exit to C$$EXIT and halt, where DSS, under
       /////   control of a host PC script, will read and record the PaSs' value.  
       /////
    }
    
    
    

    Hope this helps,
    Mark

  • Hi Mark,

    Thanks for the response. After looking through the files and other things you talk about, I think my problem is in the linker command file. I have attached it (renamed so it can be opened it in Notepad). I don't understand what is happening in the fragment you posted, particularly this:
    ...
    {
    vectors (NOLOAD)
    ...

    What does that line do? Do I need it? How does it interact with the stuff in my StkLink.cmd?

    In case that is not what is wrong, here are other answers to questions in your post.

    I am using the codec as a master and the C5515 I2S0 is the slave. I am not using DMA. My Init3204Codec() is 236 lines long, so I didn't post it yet. I can if you think it will help, but it seems to work because I correctly get both I2S clocks as an output from the codec, as seen on my logic analyzer. That should be enough for the DSP to generate an interrupt.

    Here are some more pieces you asked about. From my PowerUpInit() function:

    >>>>>>>>

    CLKSTOP = 0x0004; /* Peripheral Clock Stop Request/Acknowledge Register */
    /* Figure 1-16. - Request to stop USB clock */

    while((CLKSTOP & 0x0008)!= 0x0008); /* wait for permission to stop clock */

    PCGCR1 = 0x76B9; /* Peripheral Clock Gating Configuration Register 1
    * Figure 1-14. */
    /* Peripheral clocks enabled (enable = 0) here:
    * [15] SYSCLKDIS - SYSCLK enabled
    * [11] EMIFCG - EMIF clk enabled
    * [8] I2S0CG - I2S0 clk enabled
    * [6] I2CCG - I2C clk enabled
    * [2] UARTCG - UART clk enabled
    * [1] SPICG - SPI clk enabled */

    PCGCR2 = 0x003D; /* Peripheral Clock Gating Configuration Register 2
    * Figure 1-15. */
    /* NOTE:this STOPS the USB clock */
    /* Peripheral clocks enabled (enable = 0) here:
    * [6] ANAREGCG - enable 0X70XX registers
    * [1] SARCG - SAR clk enabled */

    /***** Reset all peripherals that are used.************************************
    *
    * The reset lines are held in reset for a time setup in the PSRCR register.
    * The status is polled to find out when reset is done and it is OK to exit.
    *
    ******* Figure numbers refer to register descriptions in sprufx5d.pdf ********/

    PSRCR = 0x2666; /* Peripheral Software Reset Counter Register */
    /* Figure 1-46. - Hold reset for 100 uSec */

    PRCR = 0x00A7; /* Peripheral Reset Control Register Figure 1-47. */
    /* Peripherals reset here (write 1 to reset)
    * [7] PG4_RST - I2S2, UART & SPI
    * [5] PG3_RST - I2S0
    * [2] SAR_RST - SAR & 0x70xx stuff
    * [1] PG1_RST - EMI
    * [0] I2C_RST - I2C */

    while((PRCR & 0x0087)!=0); /** poll for reset done **/

    /* Setup the I/O pin functions. This is specific to the xxxProject design.
    * Pins for SPI, UART, I2S2, EMIF addressing and GPIO (including RS232 control
    * lines) are setup here.
    *
    ******* Figure numbers refer to register descriptions in sprufx5d.pdf ********/

    EBSR = 0x1900; /* External Bus Selection Register Figure 1-35. */
    /* Selects I/O pin functions - for pin functions see
    * sprs645.pdf Table 4-7, Table 4-8, Table 4-9.
    * PPMODE 1 enables SPI, UART, I2S2 and GP[12:17]
    * SP1MODE 2 enables GP[11:6]
    * SP0MODE 1 enables I2S0 and GP[5:4]
    * A20_MODE selects EM_A[20]
    * A19_MODE selects EM_A[19]
    * A18_MODE selects EM_A[18]
    * A17_MODE selects EM_A[17]
    * A16_MODE selects EM_A[16]
    * A15_MODE selects EM_A[15] */

    /************ Done with peripheral clock enables and I/O pin setup ************/


    /* Initialize the I2S port *****************************************************
    *
    * Before entering here, the following bits must be initialized:
    * reset the I2S) port with pg3_RST (bit 5) in PRCR (1.7.5.2 in sprufx5d.pdf)
    * set I2S0CG = 0 in PCGCR1 to enable the I2S0 module input clock
    *
    ******* Section numbers refer to register descriptions in sprufx4a.pdf *******/

    I2SSCTRL = 0x801C; /* I2S Serializer Control Register - Section 1.3.1 */
    /* [15] = 1, ENABLE - I2S enabled
    * [10] = 0, FSPOL - I2S standard FS polarity
    * [9] = 0, CLKPOL - I2S standard clk polarity
    * [8] = 0, DATADLY - 1 bit data delay
    * [5:2] = 0111, WDLNGTH - 24 bit data word
    * [1] = 0, MODE - slave mode
    * [0] = 0, FRMT - I2S standard format*/
    I2SSRATE = 0x00; /* I2S Sample Rate Generator Register - Section 1.3.2 */
    /* Not used in slave mode */
    I2SINTMASK = 0x00; /* I2S Interrupt Mask Register - Section 1.3.8 */
    /* 0x00 - disable all I2S interrupts
    * 0x0028 - write this to enable interrupts
    * [5] XMITST - Enable TX data interrupt
    * [3] RCVST - Enable Rx data interrupt */
    delay = I2SINTFL; /* I2S Interrupt Flag Register - Section 1.3.7 */
    /* reading will clear all I2S interrupt flags
    * READ ONLY register - high means:
    * [5] XMITSTFL - new DAC data needed
    * [3] RCVSTFL - ADC data ready */

    /****** Done initializing the I2S port *******/

    >>>>>>>>

    I feel like I am close, but it doesn't work yet. Help is appreciated. Thanks

    Emeric

  • Hi Emeric,

    The vectors (NOLOAD) prevents the vector table from the runtime support library(rts55x.lib) from being placed in the output file.

    See TMS320C55x Assembly Language Tools User's Guide (SPRU280I)
    http://www.ti.com/lit/ug/spru280i/spru280i.pdf

    9.6.8 Special Section Types (DSECT, COPY, and NOLOAD)

    A NOLOAD section differs from a normal output section in one respect: the section's contents,
    relocation information, and line number information are not placed in the output module. The linker
    allocates space for the section, and it appears in the memory map listing.

    Instead of using the runtime library vector table, you are linking to your vector table called "vectors" - syntax seems correct..

    Avoid allocating the vector table to 0x04FE00 - your program will work when loaded from CCS, but it will not boot in stand-alone because the bootloader uses SARAM31 (byte address range: 0x4E000 – 0x4EFFF) page of memory as data space... Any code in SARAM31 is corrupted. After the boot process is complete, this memory space can be used.

    Did you try adding vectors (NOLOAD) to your linker .cmd file?

    Check out the .map file generated under the Debug folder after building the project.

    You should be able to see your vector table allocated at 0x04FE00. Excerpt from .map file of Audio Filter Demo project shown:

    vector       0     00001200  [ 00000900 ] 00000100          *  
                       00001200  [ 00000900 ] 00000100          *   vector.obj (vector)

    vectors      0     00001300  [ 00000980 ] 00000100          *   NOLOAD SECTION
                       00001300  [ 00000980 ] 00000100          *   rts55x.lib : vectors.obj (vectors)

    Also, you should be able to view disassembly at byte address 0x04FE00, and see your interrupt vector pointers for PROG0 & PROG1 (similar to how Audio Filter Demo points to DMA_Isr)
              RST:
    0x001200:   ca010e22                 .ivec $../vector.asm:153:216$, USE_RETA
    0x001204:   5e80_5f80                NOP_16 || NOP_16
    ...
              DMA:
    0x001240:   ea0102dd                 .ivec DMA_Isr, C54X_STK
    0x001244:   5e80_5f80                NOP_16 || NOP_16
              PROG2:
    0x001248:   ea010e9b                 .ivec dummy_isr, C54X_STK
    0x00124C:   5e80_5f80                NOP_16 || NOP_16
          

    Rebuild and study the Audio Filter Demo - it uses the same vectors.asm / vectors (NOLOAD) approach

    Upload the .map file if you still cannot get interrupts.

    It may help to copy and modify the Audio Filter Demo project.

    Regards,
    Mark

  • Hi Emeric,

    I wanted to check in and see how your design was progressing.  Have Mark's suggestions resolved your issue?

    Regards,
    Walter

  • Hi Walter,

    While this has helped me to find a few mistakes so far, I am still not getting interrupts, even after trying the latest advice.  Can you contact me at my private email?  If you need to, you can ask the Cleveland area TI rep or FAEs for it, they all know me.

    Thanks

    Emeric

  • Hi Emeric,

    Thanks for sending your source code. Good news. I was able to modify the project to enable interrupts.

    The trick is to point the interrupt vector pointers to _RST during the reset_isr immediately after power on reset.

    You must tell the linker to use entry_point = "reset_isr" instead of "_c_int00"  (reset_isr jumps to _c_int00 after initializing)

    Follow these instructions:

    Right click on the project in CCS --> Build Properties --> C5500 Linker --> Symbol Management --> "Specify program entry point for the output module (--entry_point, -e):" --> Enter "reset_isr"

    See below screenshot:

    Next, comment the lines in StkHardware.c that would overwrite the IVPs with an incorrect address:

    // asm(" @IVPD_L = #0x017B || mmap()");    /* Initialize interrupt vector pointer */
    // asm(" @IVPH_L = #0x017B || mmap()");    /* Initialize interrupt vector pointer */

    Rebuild the project.

    The following warning is expected:

    warning: entry-point symbol other than "_c_int00" specified:  "reset_isr"

    I was able to set breakpoints in both interrupt service routines and see the program halt at these breakpoints.

    Please confirm that your interrupts are now working.

    Regards,
    Mark

  • Hi Mark,

    Success!

    Apparently the entry point setting was what was causing my problems.  When the program started up, it did not run the assembly code to set the vector table pointers.  Those lines I had in StkHardware.c were just in there to see if I could get anything to set the IVPD and IVPH, so I deleted it from there and let it run in StkVectors.asm.  Things now work as expected.

    Thanks for all your help.

    Emeric