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-F28027: C2000 Launchpad, F28027, HC-SR04 Ultrasonic Sensor problem

Part Number: LAUNCHXL-F28027
Other Parts Discussed in Thread: C2000WARE

Hello there, again.

I started to work on a project which include the launchpad, 2 ultrasonic sensors, gps module, and 4 motors.
Recently i started to test more things in it, but i have some issues and maybe someone can pinpoint me to them.

One of the ultrasonic sensors i connected to the external interrupt and the other one to the eCAP module.

Thing is, the program only gets interrupted just by the eCAP module and i don't quite get why.

Also,  when i build the program in RAM configuration, i get errors which indicate that i don't have enough memory. The cmd file for linker is generic_ram plus nonbios_header.

Also, when i build it in the FLASH configuration, i get a lot of warnings which are stated like this: "creating output section "AdcRegsFile" without a SECTIONS" for example.

I don't understand if i have to modify the cmd files or how to modify them, or if i have to. 

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

#include "f2802x_common/include/clk.h"
#include "f2802x_common/include/flash.h"
#include "f2802x_common/include/gpio.h"
#include "f2802x_common/include/pie.h"
#include "f2802x_common/include/pll.h"
#include "f2802x_common/include/pwr.h"
#include "f2802x_common/include/timer.h"
#include "f2802x_common/include/pwm.h"
#include "f2802x_common/include/cap.h"
#include "f2802x_common/include/wdog.h"

// Prototype statements for functions found within this file.
interrupt void xint1_isr(void);
interrupt void ecap1_isr(void);
void InitECapture(void);

void Fail(void);

CAP_Handle myCap;
CLK_Handle myClk;
FLASH_Handle myFlash;
GPIO_Handle myGpio;
PIE_Handle myPie;
TIMER_Handle myTimer0;
PWM_Handle myPwm;

#define FALSE 0
#define TRUE 1

// Global variables for this example

volatile uint32_t distance_left = 0;  //storing distance_left in cm
volatile uint32_t start_val = 0;  // storing start value of timer0
volatile uint32_t stop_val = 0; //storing stop value of timer0
volatile uint32_t cap1 = 0;
volatile uint32_t cap2 = 0;
volatile uint32_t distance_right = 0;  //storing distance_left in cm
 uint16_t counter_ecap = 0;
 uint16_t interupt_counter_ecap = 0;

/*The keyword volatile alerts the compiler that the variable's value can change outside
 *  of the currently executing code. While removing the volatile keyword would reduce code size,
 *  it is not recommended. Removing volatile must be done with great care and only where the developer is certain doing
 *  so will not yield incorrect results.
 *
 */

#define DELAY (CPU_RATE/1000*6*510)  //Qual period at 6 samples

//#define US_LIMIT 1200000U  //limit of  about 24 ms for ultrasonic sensor
#define cpu_period 0.017


void main(void)
{
    CPU_Handle myCpu;
    PLL_Handle myPll;
    PWR_Handle myPwr;
    WDOG_Handle myWDog;
    
    // Initialize all the handles needed for this application 
    myCap = CAP_init((void *)CAPA_BASE_ADDR, sizeof(CAP_Obj));
    myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj)); 
    myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj));
    myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj));
    myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj));
    myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj));
    myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
    myTimer0 = TIMER_init((void *)TIMER0_BASE_ADDR, sizeof(TIMER_Obj));
    myPwr = PWR_init((void *)PWR_BASE_ADDR, sizeof(PWR_Obj));
    myPwm = PWM_init((void *)PWM_ePWM3_BASE_ADDR, sizeof(PWM_Obj));
    myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));

    // Perform basic system initialization    
    WDOG_disable(myWDog);
    CLK_enableAdcClock(myClk);
    (*Device_cal)();
    CLK_disableAdcClock(myClk);
    
    //Select the internal oscillator 1 as the clock source
    CLK_setOscSrc(myClk, CLK_OscSrc_Internal);
    
    // Setup the PLL for x10 /2 which will yield 60Mhz = 10Mhz * 10 / 2
    PLL_setup(myPll, PLL_Multiplier_12, PLL_DivideSelect_ClkIn_by_2);
    
    // Disable the PIE and all interrupts
    PIE_disable(myPie);
    PIE_disableAllInts(myPie);
    CPU_disableGlobalInts(myCpu);
    CPU_clearIntFlags(myCpu);
    
    // If running from flash copy RAM only functions to RAM   
#ifdef _FLASH
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif 

    // Setup a debug vector table and enable the PIE
    PIE_setDebugIntVectorTable(myPie);
    PIE_enable(myPie);

    // Register interrupt handlers in the PIE vector table
    PIE_registerPieIntHandler(myPie, PIE_GroupNumber_1, PIE_SubGroupNumber_4, (intVec_t)&xint1_isr);
    PIE_registerPieIntHandler(myPie, PIE_GroupNumber_4, PIE_SubGroupNumber_1, (intVec_t)&ecap1_isr);

    // Setup peripherals used in this example
       InitECapture();

    // Clear the counters
 //   Xint1Count = 0; // Count XINT1 interrupts

    // Initialize counters:
  //    ECap1IntCount = 0;
  //    ECap1PassCount = 0;

    // Enable XINT1 and XINT2 in the PIE: Group 1 interrupt 4 & 5
    // Enable INT1 which is connected to WAKEINT
    PIE_enableInt(myPie, PIE_GroupNumber_1, PIE_InterruptSource_XINT_1);
    CPU_enableInt(myCpu, CPU_IntNumber_1);
    
    PIE_enableInt(myPie, PIE_GroupNumber_4, PIE_InterruptSource_ECAP1);
    CPU_enableInt(myCpu, CPU_IntNumber_4);

    // Enable eCAP INTn in the PIE: Group 3 interrupt 1-6
        PIE_enableCaptureInt(myPie);
    // Enable Global Interrupts
    CPU_enableGlobalInts(myCpu);
    // Enable global Interrupts and higher priority real-time debug events:
    CPU_enableDebugInt(myCpu);
    // Initialize GPIO

       GPIO_setPullUp(myGpio, GPIO_Number_5, GPIO_PullUp_Disable);
       //GPIO_setQualification(myGpio, GPIO_Number_5, GPIO_Qual_Sync);
       GPIO_setMode(myGpio, GPIO_Number_5, GPIO_5_Mode_ECAP1);

    // GPIO28 & GPIO29 are outputs, start GPIO28 high and GPIO29 low
    //GPIO_setHigh(myGpio, GPIO_Number_28);
    GPIO_setMode(myGpio, GPIO_Number_34, GPIO_34_Mode_GeneralPurpose);
    GPIO_setDirection(myGpio, GPIO_Number_34, GPIO_Direction_Output);
    
    // GPIO0 and GPIO1 are inputs
    GPIO_setMode(myGpio, GPIO_Number_7, GPIO_7_Mode_GeneralPurpose);
    GPIO_setDirection(myGpio, GPIO_Number_7, GPIO_Direction_Input);
    //GPIO_setQualification(myGpio, GPIO_Number_7, GPIO_Qual_Sync);
    

    // Configure GPIO 0-3 as outputs
        GPIO_setMode(myGpio, GPIO_Number_0, GPIO_0_Mode_GeneralPurpose);
        GPIO_setMode(myGpio, GPIO_Number_1, GPIO_1_Mode_GeneralPurpose);
        GPIO_setMode(myGpio, GPIO_Number_2, GPIO_2_Mode_GeneralPurpose);
        GPIO_setMode(myGpio, GPIO_Number_3, GPIO_3_Mode_GeneralPurpose);

        GPIO_setDirection(myGpio, GPIO_Number_0, GPIO_Direction_Output);
        GPIO_setDirection(myGpio, GPIO_Number_1, GPIO_Direction_Output);
        GPIO_setDirection(myGpio, GPIO_Number_2, GPIO_Direction_Output);
        GPIO_setDirection(myGpio, GPIO_Number_3, GPIO_Direction_Output);

        GPIO_setHigh(myGpio, GPIO_Number_0);
        GPIO_setHigh(myGpio, GPIO_Number_1);
        GPIO_setHigh(myGpio, GPIO_Number_2);
        GPIO_setHigh(myGpio, GPIO_Number_3);


    // GPIO0 is XINT1, GPIO1 is XINT2
    GPIO_setExtInt(myGpio, GPIO_Number_7, CPU_ExtIntNumber_1);


    // Configure XINT1
    PIE_setExtIntPolarity(myPie, CPU_ExtIntNumber_1, PIE_ExtIntPolarity_FallingEdge);


    // Enable XINT1 and XINT2
    PIE_enableExtInt(myPie, CPU_ExtIntNumber_1);

//        TIMER_stop(myTimer0);
////     Configure CPU-Timer 0, 1, and 2 to interrupt every second:
////     50MHz CPU Freq, 1 second Period (in uSeconds)
//
//        //ConfigCpuTimer(&CpuTimer0, 50, 1000000);
//        TIMER_setPeriod(myTimer0, 0xFFFFFFFF);
//        TIMER_setPreScaler(myTimer0, 1);
//        TIMER_reload(myTimer0);
//        TIMER_setEmulationMode(myTimer0, TIMER_EmulationMode_RunFree);
//        TIMER_disableInt(myTimer0);

        CpuTimer0Regs.TCR.bit.TSS = 1;         // 1 = Stop timer, 0 = Start/Restart Timer

        CpuTimer0Regs.PRD.all =  0xFFFFFFFF;  // Initialize timer period to maximum

        CpuTimer0Regs.TPR.all = 0x0001; //set TDDR to 0

        CpuTimer0Regs.TCR.bit.TRB = 1;         // 1 = reload timer now

        CpuTimer0Regs.TCR.bit.FREE = 1;
        CpuTimer0Regs.TCR.bit.SOFT = 0;

        CpuTimer0Regs.TCR.bit.TIE = 0;         // 0 = Disable/ 1 = Enable Timer Interrupt

        //CpuTimer0Regs.TCR.all = 0;             // TSS = 0 = Start/Restart Timer


    for(;;) {

        GPIO_setHigh(myGpio, GPIO_Number_34); //triggering the pulses from sensor
        DELAY_US(10);
        GPIO_setLow(myGpio, GPIO_Number_34);
        //TIMER_start(myTimer0);
        //CpuTimer0Regs.TCR.bit.TRB = 1;
        DELAY_US(120);
        CpuTimer0Regs.TCR.bit.TSS = 0;
        start_val = CpuTimer0Regs.TIM.all;
        counter_ecap = ECap1Regs.TSCTR; //checking if TSCTR is modified
        CAP_enableTimestampCounter(myCap);          // Start Counter
        
        DELAY_US(30000); //waiting for echo

        if(distance_left < 50)
        {
            GPIO_setLow(myGpio, GPIO_Number_0);
            GPIO_setHigh(myGpio, GPIO_Number_1);
            GPIO_setHigh(myGpio, GPIO_Number_2);
            GPIO_setHigh(myGpio, GPIO_Number_3);
        }
        else if(distance_left < 100)
        {
            GPIO_setHigh(myGpio, GPIO_Number_0);
            GPIO_setLow(myGpio, GPIO_Number_1);
            GPIO_setHigh(myGpio, GPIO_Number_2);
            GPIO_setHigh(myGpio, GPIO_Number_3);
        }
        else if(distance_left < 150 )
        {
            GPIO_setHigh(myGpio, GPIO_Number_0);
            GPIO_setHigh(myGpio, GPIO_Number_1);
            GPIO_setLow(myGpio, GPIO_Number_2);
            GPIO_setHigh(myGpio, GPIO_Number_3);
        }
        else if(distance_left < 200)
        {
            GPIO_setHigh(myGpio, GPIO_Number_0);
            GPIO_setHigh(myGpio, GPIO_Number_1);
            GPIO_setHigh(myGpio, GPIO_Number_2);
            GPIO_setLow(myGpio, GPIO_Number_3);
        }
        else
        {
            GPIO_setHigh(myGpio, GPIO_Number_0);
            GPIO_setHigh(myGpio, GPIO_Number_1);
            GPIO_setHigh(myGpio, GPIO_Number_2);
            GPIO_setHigh(myGpio, GPIO_Number_3);
        }
    }
}


interrupt void xint1_isr(void)
{

    //temp_var = TIMER_getCount(myTimer0);
    CpuTimer0Regs.TCR.bit.TSS = 1;
    stop_val = CpuTimer0Regs.TIM.all;

    //TIMER_stop(myTimer0);

      distance_left = (((start_val - stop_val) * cpu_period) / 58.82) * 2; //  (17 * 0.000001)            //Converts Time to distance_left

    //TIMER_reload(myTimer0);
    CpuTimer0Regs.TCR.bit.TRB = 1;

    // Acknowledge this interrupt to get more from group 1
    PIE_clearInt(myPie, PIE_GroupNumber_1);
}

void InitECapture()
{
    CLK_enableEcap1Clock(myClk);

    CAP_disableInt(myCap, CAP_Int_Type_All);    // Disable all capture interrupts
    CAP_clearInt(myCap, CAP_Int_Type_All);      // Clear all CAP interrupt flags
    CAP_disableCaptureLoad(myCap);              // Disable CAP1-CAP4 register loads
    CAP_disableTimestampCounter(myCap);         // Make sure the counter is stopped

    // Configure peripheral registers
    //CAP_setCapOneShot(myCap);                   // One-shot
    CAP_setCapContinuous(myCap);
    CAP_setStopWrap(myCap, CAP_Stop_Wrap_CEVT2);// Stop at 2 events
    CAP_setCapEvtPolarity(myCap, CAP_Event_1, CAP_Polarity_Rising);    // Rising edge
    CAP_setCapEvtPolarity(myCap, CAP_Event_2, CAP_Polarity_Falling);     // Falling edge
   // CAP_setCapEvtPolarity(myCap, CAP_Event_3, CAP_Polarity_Rising);    // x edge
   // CAP_setCapEvtPolarity(myCap, CAP_Event_4, CAP_Polarity_Falling);     // x edge

    CAP_setCapEvtReset(myCap, CAP_Event_1, CAP_Reset_Disable);   // absolute
    CAP_setCapEvtReset(myCap, CAP_Event_2, CAP_Reset_Enable);   // Difference operation
   // CAP_setCapEvtReset(myCap, CAP_Event_3, CAP_Reset_Enable);   // Difference operation
   // CAP_setCapEvtReset(myCap, CAP_Event_4, CAP_Reset_Enable);   // Difference operation

    CAP_enableSyncIn(myCap);                    // Enable sync in
    CAP_setSyncOut(myCap, CAP_SyncOut_SyncIn);  // Pass through


    CAP_enableCaptureLoad(myCap);

    //CAP_enableTimestampCounter(myCap);          // Start Counter
    CAP_rearm(myCap);                           // arm one-shot
    CAP_enableCaptureLoad(myCap);               // Enable CAP1-CAP4 register loads
    CAP_enableInt(myCap, CAP_Int_Type_CEVT2);   // 4 events = interrupt CEVT2
}

__interrupt void ecap1_isr(void)
{
    cap1 = CAP_getCap1(myCap);
    cap2 = CAP_getCap2(myCap);

    distance_right = (((cap2 - cap1) * cpu_period) / 58.82);// * 2;


    CAP_disableTimestampCounter(myCap);         // Make sure the counter is stopped

    interupt_counter_ecap = ECap1Regs.TSCTR; //checking if TSCTR is modified in ISR


    CAP_clearInt(myCap, CAP_Int_Type_CEVT2);
    CAP_clearInt(myCap, CAP_Int_Type_Global);


    CAP_rearm(myCap);

    // Acknowledge this interrupt to receive more interrupts from group 4
    PIE_clearInt(myPie, PIE_GroupNumber_4);
}

void Fail()
{
    __asm("   ESTOP0");
}


//===========================================================================
// No more.
//===========================================================================

  • Hi Sergui,

    Please refer to Control Suite example to get more help in constructing .cmd file. You can even use the one in the examples in your code.

    C:\ti\c2000\C2000Ware_1_00_04_00\device_support\f2802x\examples\drivers

    Regards,
    Nirav
  • Hello, Nirav Ginwala.
    My code there is, actually, composed of 2 examples: one with ECAP and one with external interrupt, and they are modified in the way I want to use them.
    I guess my mistake is that i don't treat the interrupts correctly.
    And about your advice, excuse me but i don't understand. Which example are you talking about?
  • Hi,

    You can use example - C:\ti\c2000\C2000Ware_1_00_04_00\device_support\f2802x\examples\drivers\ecap_apwm

    Under build configuration, you can "Set Active" as "Flash" and build the .out to see how to fix the errors you are getting when you build with flash configuration, most likely you will have to define sections in .cmd file to fix the errors.

    There are also linker command files under C:\ti\c2000\C2000Ware_1_00_04_00\device_support\f2802x\common\cmd directory, that you can use as reference to fix.

    Regards,
    Nirav
  • Thank you for your response.
    I already looked into that example.

    But for the cmd file, i compared the two versions i have of F2802x_generic_ram.cmd. One is from 2012 and other is from 2018.
    In 2018 version there is this line: RAML0 : origin = 0x008000, length = 0x000800. Well, the length is different, in older version it is 400.
    And now it kinda works.
    Still i don't quite get from datasheet or what i found on forum how should i create new memory pages or sections, or to split memory.

    And, at this point, the interrupt from external interrupt source doesn't work.
  • Is your issue resolved, or are you still seeing it?

    Regards,
    Nirav
  • Hello there.
    Somehow yes, but i can't really explain it very well.
    I had to change cmd files from nonBIOS to BIOS, because for the final project i'll have run my project from FLASH.
    Still it's quite hard to get the thing how i need to create new memory blocks in case i'll run out of it.
    And the way i think my code for the project itself it's quite not correct because there are things about f28027 that i don't really get.

    At this point i'm trying to get how to read data from a TC6000GN gps module with this launchpad. Until i'll run into more unknown problems.

    Thank you.