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/TMS320F28379D: #TMS320F28379D #C2000 WARE #IPC #BOOT

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Tool/software: Code Composer Studio

Hi,

I am trying to synchronize both my CPU01 and CPU02 using the IPC flags .I am running both the codes on their respective RAMs.The problem is the below line 

 IpcRegs.IPCSET.bit.IPC17 = 1;  

is not getting set to one , that is IPC17 bit is not getting set to one in CPU02 code .

i have attached both codes below .

//
// Included Files
//
#include "F28x_Project.h"
#include "F2837xD_Ipc_drivers.h"


#define REFERENCE_VDAC        3
#define REFERENCE_VREF        2
#define DACA                  1
#define REFERENCE             REFERENCE_VDAC
#define CPUFREQ_MHZ           200
#define DAC_NUM               DACA   // pin no 30

void ConfigureADC(void);
void SetupADCContinuous(Uint16 channel);
void configureDAC(Uint16 dac_num);
interrupt void cpu_timer0_isr(void);


volatile struct DAC_REGS* DAC_PTR[4] = {0x0,&DacaRegs,&DacbRegs,&DaccRegs};
Uint32 samplingFreq_hz = 5000;
float freqResolution_hz = 0;
float cpuPeriod_us = 0;
Uint32 interruptCycles = 0;
float interruptDuration_us = 0;
float samplingPeriod_us = 0;

//
// Main
//
void main(void)
{
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
//
    InitSysCtrl();
//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xD_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
    InitGpio();

//
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
//
    DINT;

//
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2837xD_PieCtrl.c file.
//
    InitPieCtrl();
    IpcRegs.IPCCLR.all = 0xFFFFFFFF;
    PieCtrlRegs.PIEIER1.bit.INTx13 = 1;     // IPC0 ISR
    IER |= 0x0001;                          // Enable INT1 in IER to enable PIE group 1
//
// Disable CPU interrupts and clear all CPU interrupt flags:
//
   // IER = 0x0000;
    IFR = 0x0000;

//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
//
    InitPieVectTable();

//
// Enable global Interrupts and higher priority real-time debug events:
//
    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM

//
// Spin here until CPU02 is ready
//
    while(!IPCRtoLFlagBusy(IPC_FLAG17));
    IPCRtoLFlagAcknowledge(IPC_FLAG17);

//
// Transfer ownership of ADCA to CPU02
//
           EALLOW;
           DevCfgRegs.CPUSEL11.bit.ADC_C = 1;
           DevCfgRegs.CPUSEL14.bit.DAC_B = 1;
           EDIS;

    ConfigureADC();
    SetupADCContinuous(3);
//
// Map Cpu Timer0 interrupt function to the PIE vector table
//
        EALLOW;
        PieVectTable.TIMER0_INT = &cpu_timer0_isr;
        EDIS;

        cpuPeriod_us = (1.0/CPUFREQ_MHZ);
        samplingPeriod_us = (1000000.0/samplingFreq_hz);

        configureDAC(DAC_NUM);                   // Configure DAC

        InitCpuTimers();                                 // Initialize Cpu Timers

//
// Configure Cpu Timer0 to interrupt at specified sampling frequency
//
        ConfigCpuTimer(&CpuTimer0, CPUFREQ_MHZ, 1000000.0/samplingFreq_hz);

//
// Start Cpu Timer0
//
        CpuTimer0Regs.TCR.all = 0x4000;

//
// Enable interrupt
//
        IER |= M_INT1;
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;                 // enable interrupt 1.7 (TIMER0)
        EINT;
        ERTM;



       do                 // take conversions indefinitely in loop
         {
//
//enable ADCINT flag
//
         EALLOW;
         AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;
         AdcaRegs.ADCINTFLGCLR.all = 0x000F;
         EDIS;

         AdcaRegs.ADCSOCFRC1.all = 0x0001;     //software force start SOC0
         AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;// make sure INT1 flag is cleared
//
//disable  ADCINT flag to stop sampling
//
         EALLOW;
         AdcaRegs.ADCINTSEL1N2.bit.INT1E = 0;
         EDIS;
      }while(1);
}
//
//DAC configuration
//
void configureDAC(Uint16 dac_num)
{
    EALLOW;
    DAC_PTR[dac_num]->DACCTL.bit.DACREFSEL = REFERENCE;
    DAC_PTR[dac_num]->DACOUTEN.bit.DACOUTEN = 1;
    DAC_PTR[dac_num]->DACVALS.all = 0;
    DELAY_US(1000); // Delay for buffered DAC to power up
    EDIS;
}
//
// ConfigureADC - Write ADC configurations and power up the ADC for both
//                ADC A and ADC B
void ConfigureADC(void)          //write configurations
       {
          EALLOW;
          AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
          AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
          AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;          //Set pulse positions to late
          AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;             //power up the ADC
          DELAY_US(1000);//delay for 1ms to allow ADC time to power up
          EDIS;
      }

      //
      // SetupADCContinuous - setup the ADC to continuously convert on one channel
      //
void SetupADCContinuous(Uint16 channel)
{
  //  Uint16 acqps;

    //
    // Determine minimum acquisition window (in SYSCLKS) based on resolution
    //
   /* if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION)
    {
        acqps = 14; //75ns
    }
    else //resolution is 16-bit
    {
        acqps = 63; //320ns
    }
*/
    EALLOW;
    AdcaRegs.ADCSOC0CTL.bit.CHSEL  = channel;  //SOC will convert on channel
    AdcaRegs.ADCSOC0CTL.bit.ACQPS  = 14;
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 0; //disable INT1 flag
    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 1;
    AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 2;
    EDIS;
}

interrupt void cpu_timer0_isr(void)
    {
       CpuTimer1Regs.TCR.all = 0x0000;            // Start Cpu Timer1 to indicate begin of interrupt
//
// Write current ADC value to buffered DAC A(A0 pin no 30)
//
       DAC_PTR[DAC_NUM]->DACVALS.all = AdcaResultRegs.ADCRESULT0;     // ADCC C3 pin no 24

       PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;       // Acknowledge this interrupt to receive more interrupts from group 1
       CpuTimer1Regs.TCR.all = 0x0010;               // Stop Cpu Timer1 to indicate end of interrupt
       interruptCycles = 0xFFFFFFFFUL - CpuTimer1Regs.TIM.all;  // Calculate interrupt duration in cycles
       interruptDuration_us = cpuPeriod_us * interruptCycles;   // Calculate interrupt duration in micro seconds
       CpuTimer1Regs.TCR.all = 0x0030;               // Reload Cpu Timer1
    }

//
// Included Files

//

#include "F28x_Project.h"

#include "F2837xD_Ipc_drivers.h"


#define REFERENCE_VDAC        3

#define REFERENCE_VREF        2

#define DACB                  2

#define REFERENCE             REFERENCE_VDAC

#define CPUFREQ_MHZ1           200

#define DAC_NUM1              DACB   // pin no 70


void ConfigureADC1(void);

void SetupADCContinuous1(Uint16 channel1);

void configureDAC1(Uint16 dac_num1);

interrupt void cpu_timer1_isr(void);


volatile struct DAC_REGS* DAC_PTR[4] = {0x0,&DacaRegs,&DacbRegs,&DaccRegs};

Uint32 samplingFreq_hz1 = 5000;

float freqResolution_hz1 = 0;

float cpuPeriod_us1 = 0;

Uint32 interruptCycles1 = 0;

float interruptDuration_us1 = 0;

float samplingPeriod_us1 = 0;



//

// Main

//

void main(void)

{

InitSysCtrl();
    
DINT;      
// Disable CPU interrupts
  
InitPieCtrl();
// Initialize the PIE control registers to their default state.


// Disable CPU interrupts and clear all CPU interrupt flags:

    
IER = 0x0000;

IFR = 0x0000;

    
InitPieVectTable();

//

//--- Let CPU1 know that CPU2 is ready

       IpcRegs.IPCSET.bit.IPC17 = 1;     // Set IPC17 to release CPU1



//
// Power up the ADC_B and DAC_B

//
   
       EALLOW;

       CpuSysRegs.PCLKCR13.bit.ADC_C = 1;
 
       CpuSysRegs.PCLKCR16.bit.DAC_B = 1;

       ConfigureADC1(); // Configure the ADC and power it up
   
       SetupADCContinuous1(3);// Setup the ADC for continuous conversions on channel 0

    
       EINT;  // Enable Global interrupt INTM
  
       ERTM;  // Enable Global realtime interrupt DBGM

    
//

// Map Cpu Timer0 interrupt function to the PIE vector table
 
//

       EALLOW;
     
       PieVectTable.TIMER0_INT = &cpu_timer1_isr;
       
       EDIS;

 
       cpuPeriod_us1 = (1.0/CPUFREQ_MHZ1);
      
       samplingPeriod_us1 = (1000000.0/samplingFreq_hz1);

     
       configureDAC1(DAC_NU      // Configure DAC

    
       InitCpuTimers();        // Initialize Cpu Timers


//

// Configure Cpu Timer0 to interrupt at specified sampling frequency
 
//
 
       ConfigCpuTimer(&CpuTimer0, CPUFREQ_MHZ1, 1000000.0/samplingFreq_hz1);

//
    
// Start Cpu Timer0
    
//
     
       CpuTimer0Regs.TCR.all = 0x4000;

  
//
    
// Enable interrupt
   
//
         
      IER |= M_INT1;
     
      PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
  
      EINT;
      
      ERTM;




  do                 // take conversions indefinitely in loop
     
     {
    //
    //enable ADCINT flag
    //
      
      EALLOW;
      
      AdccRegs.ADCINTSEL1N2.bit.INT1E = 1;
       
      AdccRegs.ADCINTFLGCLR.all = 0x000F;
      
      EDIS;

      
      AdccRegs.ADCSOCFRC1.all = 0x0001;     //software force start SOC0
       
      AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
// make sure INT1 flag is cleared
   
//
    
//disable  ADCINT flag to stop sampling
    
//
      
       EALLOW;
  
       AdccRegs.ADCINTSEL1N2.bit.INT1E = 0;
      
       EDIS;
     
     }while(1);
   
 }
    
//
    
//DAC configuration
    
//
    
void configureDAC1(Uint16 dac_num1)

    {

      EALLOW;

      DAC_PTR[dac_num1]->DACCTL.bit.DACREFSEL = REFERENCE;

      DAC_PTR[dac_num1]->DACOUTEN.bit.DACOUTEN = 1;
  
      DAC_PTR[dac_num1]->DACVALS.all = 0;
  
      DELAY_US(1000); // Delay for buffered DAC to power up

      EDIS;
   
    }
    
//
    
// ConfigureADC - Write ADC configurations and power up the ADC for both
  
//                ADC A and ADC B
    
void ConfigureADC1(void)         //write configurations
       
    {
   
     EALLOW;
   
     AdccRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
    
     AdcSetMode(ADC_ADCC, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
 
     AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1;          //Set pulse positions to late
        
     AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1;             //power up the ADC
       
     DELAY_US(1000);//delay for 1ms to allow ADC time to power up
         
     EDIS;
      
    }

          
//

// SetupADCContinuous - setup the ADC to continuously convert on one channel
 
//
    
void SetupADCContinuous1(Uint16 channel1)
 
   {
    
    EALLOW;
      
    AdccRegs.ADCSOC0CTL.bit.CHSEL  = channel1;  //SOC will convert on channel
    
    AdccRegs.ADCSOC0CTL.bit.ACQPS  =14;
       
    AdccRegs.ADCINTSEL1N2.bit.INT1E = 0; //disable INT1 flag
   
    AdccRegs.ADCINTSEL1N2.bit.INT1SEL = 1;
  
    AdccRegs.ADCINTSOCSEL1.bit.SOC0 = 2;
    
    EDIS;

    }


interrupt void cpu_timer1_isr(void)
 
       {
    
      CpuTimer1Regs.TCR.all = 0x0000;    // Start Cpu Timer1 to indicate begin of interrupt

//

// Write current ADC value to buffered DAC A(A0 pin no 30)

//

 
      DAC_PTR[DAC_NUM1]->DACVALS.all = AdccResultRegs.ADCRESULT0;     // ADC_A3 pin no 25
     
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;       // Acknowledge this interrupt to receive more interrupts from group 1
     
      CpuTimer1Regs.TCR.all = 0x0010;               // Stop Cpu Timer1 to indicate end of interrupt
     
      interruptCycles1 = 0xFFFFFFFFUL - CpuTimer1Regs.TIM.all;  // Calculate interrupt duration in cycles
  
      interruptDuration_us1 = cpuPeriod_us1 * interruptCycles1;   // Calculate interrupt duration in micro seconds

      CpuTimer1Regs.TCR.all = 0x0030;               // Reload Cpu Timer1

        }

Regards,

Ashwin

  • Ashwin

    Is it not functionally working as expected? Your usage looks correct.
    If you're looking at the IPCSET register, you won't see it set to 1. The set will be reflected in the IPCFLG register.

    Best regards
    Chris
  • Christopher,

    I checked the IPCFLG register as suggested but there is no change .

    My Build and Debug process is as follows:

    1) In the Project Explorer window click on the adc_epwm_cpu01 project to set it active. Then click the Build button and watch the tools run in the Console window. Check for any errors in the Problems window. Repeat this step for the adc_epwm_cpu02 project.

    2) Again, in the Project Explorer window click on the adc_epwm_cpu01 project to set it active. Click on the Debug button (green bug). A Launching Debug Session window will open. Select only CPU1 to load the program on (i.e. uncheck CPU2), and then click OK. The CCS Debug perspective view should open, then CPU1 will connect to the target and the program will load automatically.

    3)The Debug window reflects the current status of CPU1 and CPU2.

    4) Next, we need to connect to and load the program on CPU2. Right-click at the line “Texas Instruments XDS100v2 USB Emulator_0/C28xx_CPU2” and select Connect Target.

    5) With the line “Texas Instruments XDS100v2 USB Emulator_0/C28xx_CPU2” still highlighted, load the program: Run - >Load -> Load Program…
    Browse to the file : C:\ti\c2000\C2000Ware_1_00_06_00\device_support\f2837xd\examples\dual\adc_epwm\cpu02\ccs\CPU2_RAM\adc_epwm_cpu02.out and select
    OK to load the program.

    6)Again, with the line “Texas Instruments XDS100v2 USB Emulator_0/C28xx_CPU1”highlighted, set the bootloader mode using the menu bar by clicking:
    Scripts -> EMU Boot Mode Select ->EMU_BOOT_SARAM
    Use the same procedure above to set the bootloader mode for CPU2.



    Is anything wrong in the Build and Degub procedure?

    Run procedure:
    7) In the Debug window, click on the line “Texas Instruments XDS100v2 USB Emulator_0/C28xx_CPU1”. Run the code on CPU1 by clicking the green Resume button. At this point CPU1 is running.

    8)In the Debug window, click on the line “Texas Instruments XDS100v2 USB Emulator_0/C28xx_CPU2”. As before, run the code on CPU2 by clicking the Resume button.


    Regards,
    Ashwin
  • Ashwin

    Nothing seems incorrect about your procedure. You've stepped through the code and you don't see it set when you do that?
    What if you try setting IPC17 using the "all" type or use driverlib? Ex: IpcRegs.IPCSET.all |= 0x20000;

    Best regards
    Chris
  • Hi,
    Christopher

    I tried the changes told by you , but it reflects no changes .
    But ,
    I get this: Break at address "0x3fec52" with no debug information available, or outside of program code.
    while i try to connect target for the CPU02 , does that have anything to do with the IPC flags not being enabled (just asking out of curiosity ).

    Thanks and Regards,
    Ashwin
  • Ashwin

    I couldn't say, but doubt it has to do with the IPC flags.
    Are you able to run successfully the IPC example from C2000Ware?
    Load code to CPU1 and CPU2. Then reset CPU2 via CCS and run CPU2. Then run CPU1.

    Best regards
    Chris
  • Chris,

     Are you able to run successfully the IPC example from C2000Ware?

    No the IPC examples are not working.

     

    Regards,

    Ashwin

  • Ashwin

    What behavior are you seeing?
    If CPU1 is getting stuck waiting for CPU2 to "boot", make sure to load code to CPU2 and then reset it, run it. Then run CPU1, this will then command CPU2 to boot.

    Best regards
    Chris
  • Ashwin

    I haven’t heard from you for 2 weeks, so I’m assuming you were able to resolve your issue. If this isn’t the case, please reject this resolution and reply to this thread. If this thread locks, please click the "Ask a related question" button and in the new thread describe the current status of your issue and any additional details you may have to assist us in helping to solve your issues.

    Regards,
    Chris