Quantcast
Viewing all articles
Browse latest Browse all 262198

Compiler/TMS320C6748: Using TI calls to set/reset a pin versus use a struct

Part Number:TMS320C6748

Tool/software: TI C/C++ Compiler

I have seen a strange behavior I somply don't understand:

I have worked with the Delfino controllers and really enjoyed the struct mechanism to access registers and bits within the peripherals and I thought I would try the same for 6748 DSP.

So I made a header file with structs to define the GPIO registers and bits based on the way it is done for the 2000 series. See file.

Also I made a little test file to see how it works. See file.

And now comes the strange stuff:
When I single step the     "GPIOPinWrite( SOC_GPIO_0_REGS, GPIO_PIN_NUMBER(6,6), 1 );" and the "GpioBanks.B6_7.SET.bit.SETA6 = 1;" lines, I got two very different results when counting the clock pulses in Timer 2.

For the TI call (GPIOPinWrite) the number of clock pulses are around 25 to 30 and when I test the struct the number of pulses is 3 to 5. Looks like a huge improvement: 5 times faster when using the struct way.

Great, let's try it in real time without the debugger: Now it turns out the TI call is faster (~40%?) than the struct way. Bummer. I looked at the actual pin, GPIO 6,6, on a  scope.

But how come it seems faster when using the debugger as compared to the free run?

Any good explanation?

Thanks,

Claus Knudsen

//CODE

/*
 * main.c
 */

#include "psc.h"

#include "soc_C6748.h"
#include "gpio.h"
#include "pll_regs.h"
#include "timer.h"

#include "C6000GPIOStruct.h"

#define GPIO_PIN_NUMBER(BANK,PINNR) (BANK * 16 + PINNR + 1)

void TestGPIO_STRUCT (void);
void ConfigandStartTimer_2( void );



int main(void) {
	
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON,
           PSC_MDCTL_NEXT_ENABLE);

    PINMUX14 = 0x00000080;      // set pin to GPIO(6,6)

    GPIODirModeSet( SOC_GPIO_0_REGS, GPIO_PIN_NUMBER(6,6), GPIO_DIR_OUTPUT );

    ConfigandStartTimer_2();

    while (1)
	{
	    TestGPIO_STRUCT();
	}
}



#pragma DATA_SECTION(GpioBanks , "GPIO_REG");
volatile struct GPIO_BANKS_0_8 GpioBanks;


void TestGPIO_STRUCT (void)
{

    GPIOPinWrite( SOC_GPIO_0_REGS, GPIO_PIN_NUMBER(6,6), 1 ); // step
    GPIOPinWrite( SOC_GPIO_0_REGS, GPIO_PIN_NUMBER(6,6), 0 ); // step


    // Use the struct two times in order to distinguish between the TI call and the struct
    GpioBanks.B6_7.SET.bit.SETA6 = 1;
    GpioBanks.B6_7.CLR.bit.CLRA6 = 1;
    GpioBanks.B6_7.SET.bit.SETA6 = 1;
    GpioBanks.B6_7.CLR.bit.CLRA6 = 1;


}


void ConfigandStartTimer_2( void )
{
    TimerConfigure( SOC_TMR_2_REGS, TMR_CFG_64BIT_CLK_INT);

    TimerPeriodSet( SOC_TMR_2_REGS, TMR_TIMER12, 0xFFFFFFFF );
    TimerPeriodSet( SOC_TMR_2_REGS, TMR_TIMER34, 0xFFFFFFFF );

    TimerEnable( SOC_TMR_2_REGS, TMR_TIMER12, TMR_ENABLE_CONT);
}


// STRUCT

/*
 * main.c
 */

#include "psc.h"

#include "soc_C6748.h"
#include "gpio.h"
#include "pll_regs.h"
#include "timer.h"

#include "C6000GPIOStruct.h"

#define GPIO_PIN_NUMBER(BANK,PINNR) (BANK * 16 + PINNR + 1)

void TestGPIO_STRUCT (void);
void ConfigandStartTimer_2( void );



int main(void) {
    
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON,
           PSC_MDCTL_NEXT_ENABLE);

    PINMUX14 = 0x00000080;      // set pin to GPIO(6,6)

    GPIODirModeSet( SOC_GPIO_0_REGS, GPIO_PIN_NUMBER(6,6), GPIO_DIR_OUTPUT );

    ConfigandStartTimer_2();

    while (1)
    {
        TestGPIO_STRUCT();
    }
}



#pragma DATA_SECTION(GpioBanks , "GPIO_REG");
volatile struct GPIO_BANKS_0_8 GpioBanks;


void TestGPIO_STRUCT (void)
{

    GPIOPinWrite( SOC_GPIO_0_REGS, GPIO_PIN_NUMBER(6,6), 1 ); // step
    GPIOPinWrite( SOC_GPIO_0_REGS, GPIO_PIN_NUMBER(6,6), 0 ); // step


    // Use the struct two times in order to distinguish between the TI call and the struct
    GpioBanks.B6_7.SET.bit.SETA6 = 1;
    GpioBanks.B6_7.CLR.bit.CLRA6 = 1;
    GpioBanks.B6_7.SET.bit.SETA6 = 1;
    GpioBanks.B6_7.CLR.bit.CLRA6 = 1;


}


void ConfigandStartTimer_2( void )
{
    TimerConfigure( SOC_TMR_2_REGS, TMR_CFG_64BIT_CLK_INT);

    TimerPeriodSet( SOC_TMR_2_REGS, TMR_TIMER12, 0xFFFFFFFF );
    TimerPeriodSet( SOC_TMR_2_REGS, TMR_TIMER34, 0xFFFFFFFF );

    TimerEnable( SOC_TMR_2_REGS, TMR_TIMER12, TMR_ENABLE_CONT);
}


// Linker CMD file

// ============================================================================
// Linker Command File for Linking c674 DSP Programs
//
// These linker options are for command line linking only. For IDE linking,
// you should set your linker options in Project Properties.
//         -c                    Link Using C Conventions
//        -stack     0x1000        Software Stack Size
//        -heap    0x1000        Heap Area Size
// ===========================================================================
-stack 0x3000
//-heap 0x2000

// ============================================================================
//                         Specify the System Memory Map
// ============================================================================
MEMORY
{
    L1P:        o = 0x11E00000          l = 0x00008000
    L1D:        o = 0x11F00000          l = 0x00008000
    L2:         o = 0x11800000          l = 0x00040000
    SHARED_RAM: o = 0xC0000000          l = 0x00100000
    DDR2:       o = 0xC0100000          l = 0x07F00000
    EMIFA2      o = 0x60000000          l = 0x02000000
    GPIOMEM     o = 0x01E26010          l = 0xC8
}

// ============================================================================
//                 Specify the Sections Allocation into Memory
// ============================================================================
SECTIONS
{


    .cinit        >        L2               // Initialization Tables
    .pinit        >        SHARED_RAM//DDR2
    .init_array   >        L2               //
    .binit        >        L2               // Boot Tables
    .const        >        SHARED_RAM       //DDR2//L2               // Constant Data. was L2, now DDR2 with fpga code
    .switch       >        L2               // Jump Tables
    .text         >       L2// DDR2               // Executable Code
    .text:_c_int00: align=1024 > L2         // Entrypoint
    


    GROUP (NEARDP_DATA)                       // group near data
    {
       .neardata
       .rodata
       .bss                                   // note: removed fill = 0
    }             >        L2
    .far: fill = 0x0, load > L2             // Far Global & Static Variables
    .fardata      >        L2               // Was L2. Far RW Data
    .stack        >        L2               // Software System Stack
    .sysmem       >        L2               // Dynamic Memory Allocation Area
    .heap         >        DDR2
    {
      . += 0x01000000;
    }
    .cio          >        L2               // C I/O Buffer
    .vecs         >        L2               // Interrupt Vectors

    FPGASection   >        EMIFA2
    DDR2Funcs     >        DDR2
    SharedRAMFuncs >       SHARED_RAM
    LEVEL2        >        L2
    FASTMEM: fill = 0x0      >         L1D
    FASTPROG > L1P
    GPIO_REG > GPIOMEM
}




Viewing all articles
Browse latest Browse all 262198

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>