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/UCD3138: Error: No PMBus devices responded to a DEVICE_ID request; No ROM detected: read block error while getting ROM version

Part Number: UCD3138

Tool/software: Code Composer Studio

Hello, 

Below is my code which just wants to use an interrupt to change the duty cycle of PWM.

I have two questions.

1.  The GUI reports this:

22:38:46.655 No ROM detected: read block error while getting ROM version

when I add this sentence CimRegs.FIRQPR.bit.FIRQ_DPWM0 = 1; // set to FIQ mode (Red in the code below).

 

2. If I exclude this sentence, just a fixed duty cycle of PWM can work. Even in this condition, the UCD3138 cannot stay in ROM. The GUI reports that 

22:45:03.153 Found DC-DC HSFB Firmware v0.0.11.105 @ Address 88d in program mode

But, I want it to work in ROM mode so that I can use the memory debug.

Could you tell me how to solve this problem? Thank you so much!!!

 

#define MAIN 1

#include "system_defines.h"
#include "Cyclone_Device.h"
#include "pmbus_commands.h"
#include "pmbus_common.h"
#include "pmbus_topology.h"
#include "variables.h"
#include "functions.h"
#include "software_interrupts.h"
#include "cyclone_defines.h"
#include "stdio.h"

#define PCLK_PERIOD 4.0e-9
#define PERIOD_SECONDS 10.0e-6
#define PERIOD ((int)(PERIOD_SECONDS/PCLK_PERIOD)<<4)
#define EVENT1 (int)(PERIOD*0.2)

float temp= 0.2;

void init_dpwm0(void)
{
Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 0; // disable DPWM0 locally during initilization

Dpwm0Regs.DPWMCTRL0.bit.CLA_EN = 0; // default is 1 (i.e. default is to use the filter output to control DPWM)

Dpwm0Regs.DPWMPRD.all = PERIOD; // use .all for all values, so that the scaling matches
Dpwm0Regs.DPWMEV1.all = EVENT1; // set EVENT 1 to 0% (start) of period

Dpwm0Regs.DPWMINT.bit.PRD_INT_EN = 1; //open DPWM0 interrupt
Dpwm0Regs.DPWMINT.bit.PRD_INT_SCALE = 0011; //Period Interrupt generated once every 6 switching cycles
CimRegs.FIRQPR.bit.FIRQ_DPWM0 = 1; // set to FIQ mode


Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 1; // enable DPWM0 locally
LoopMuxRegs.GLBEN.bit.DPWM0_EN = 1; // enable DPWM0 globally
}


void main()
{

if(GioRegs.FAULTIN.bit.FLT3_IN == 0)
{
clear_integrity_word();
}

init_pmbus(0x58); // initialize PMBus handler
init_dpwm0(); // initialize DPWM0
for(;;)
{
pmbus_handler();
}
}


#pragma INTERRUPT(c_int00,RESET)
void c_int00(void)
{
main();
}

#pragma INTERRUPT(ADCValueGet,FIQ)
void ADCValueGet(void)
{

temp=temp+0.01;
if(temp>0.9)
{
temp=0.2;
}

Dpwm0Regs.DPWMEV1.all = temp*PERIOD;

Dpwm0Regs.DPWMINT.bit.PRD = 0; //clear the flag
//from the pdf: read_scrap = Dpwm3Regs.DPWMINT.bit.PRD;
}

  • I use the demo board UCD3138CC64EVM-030

  • You can not be in ROM when you are running your program.

    UCD will run your firmware or the ROM, execution of these are mutually exclusive.

    ROM is just a separate bootloader program.

    Many TI EVM firmware have Memory debugger support when running the firmware without needing to switch to ROM mode.

    The memory debugger support is enabled by Parm Info and Parm Value commands in the firmware.

    I suggest that you download and use one of these EVM firmware that support memory debugger.

    You will even be able to access your C language variables and not only the registers.

    Hope this makes sense.

    Regards,

  • Thank you, Yitzhak Bolurian! Your answer solved my second question. Now I could use the Memory debugger with Scan for devices with DEVICE_ID.

    However, Whenever I add this sentence:

    CimRegs.FIRQPR.bit.FIRQ_DPWM0 = 1; // set to FIQ mode 

    or 

    //Disable interrupts
    disable_interrupt();
    disable_fast_interrupt();
    //This is necessary to make sure all interrupt status values are
    //cleared. Added here by ZCS feature
    FAULTMUXINTSTAT_value = FaultMuxRegs.FAULTMUXINTSTAT.all;
    //Configure IRQ
    write_reqmask(CIMINT_ALL_DPWM0 | CIMINT_ALL_FAULT_MUX);
    //Configure FIQ
    write_firqpr(CIMINT_ALL_DPWM0 | CIMINT_ALL_FAULT_MUX);
    // Enable interrupts
    enable_fast_interrupt();
    enable_interrupt();

    (ps: I think those two part mean the same thing. Am I right?)

    The Fusion digital power firmware download tool shows this problem.

    Is there anything wrong with my code?

    The attachment is my code. I just want to change the PWM duty cycle in the interrupt service routine. Thank you so much!!

    2235.main.c
    #define MAIN 1
    
    #include "system_defines.h"
    #include "Cyclone_Device.h"
    #include "pmbus_commands.h"
    #include "pmbus_common.h"
    #include "pmbus_topology.h"
    #include "variables.h"
    #include "functions.h"
    #include "software_interrupts.h"
    #include "cyclone_defines.h"
    #include "stdio.h"
    
    #define PCLK_PERIOD		4.0e-9
    #define PERIOD_SECONDS	10.0e-6
    #define PERIOD			((int)(PERIOD_SECONDS/PCLK_PERIOD)<<4)
    #define EVENT1			(int)(PERIOD*0.2)
    
    Uint32 FAULTMUXINTSTAT_value;
    float temp= 0.2;
    
    void init_dpwm0(void)
    {
        Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 0;     // disable DPWM0 locally during initilization
    
    	Dpwm0Regs.DPWMCTRL0.bit.CLA_EN = 0;		// default is 1 (i.e. default is to use the filter output to control DPWM)
    
    	Dpwm0Regs.DPWMPRD.all = PERIOD;         // use .all for all values, so that the scaling matches
    	Dpwm0Regs.DPWMEV1.all = EVENT1;         // set EVENT 1 to 0% (start) of period
    
        Dpwm0Regs.DPWMINT.bit.PRD_INT_EN = 1;   //open DPWM0 interrupt
    	Dpwm0Regs.DPWMINT.bit.PRD_INT_SCALE = 0010; //Period Interrupt generated once every 4 switching cycles
    //	CimRegs.FIRQPR.bit.FIRQ_DPWM0 = 1;  // set to FIQ mode
    
        Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 1;     // enable DPWM0 locally
    	LoopMuxRegs.GLBEN.bit.DPWM0_EN = 1;     // enable DPWM0 globally
    }
    
    
    void main()
    {
    
    	if(GioRegs.FAULTIN.bit.FLT3_IN == 0)
    	{
    		clear_integrity_word();
    	}
    
    	init_pmbus(0x58);						// initialize PMBus handler
    
    
    	//��ʼ���жϳ���
    	    //Disable interrupts
    	    disable_interrupt();
    	    disable_fast_interrupt();
    	    //This is necessary to make sure all interrupt status values are
    	    //cleared. Added here by ZCS feature
    	    FAULTMUXINTSTAT_value = FaultMuxRegs.FAULTMUXINTSTAT.all;
    	    //Configure IRQ
    	    write_reqmask(CIMINT_ALL_DPWM0 | CIMINT_ALL_FAULT_MUX);
    	    //Configure FIQ
    	    write_firqpr(CIMINT_ALL_DPWM0 | CIMINT_ALL_FAULT_MUX);
    //	    Enable interrupts
    	    enable_fast_interrupt();
    	    enable_interrupt();
    
    	init_dpwm0();							// initialize DPWM0
    
        //This is necessary to make sure all interrupt status values are
        //cleared.
        FAULTMUXINTSTAT_value = FaultMuxRegs.FAULTMUXINTSTAT.all;
    
    	for(;;)
    	{
    		pmbus_handler();
    	}
    }
    
    
    //#pragma INTERRUPT(c_int00,RESET)
    void c_int00(void)
    {
    	main();
    }
    
    #pragma INTERRUPT(ADCValueGet,IRQ)
    void ADCValueGet(void)
    {
    
        temp=temp+0.01;
        if(temp>0.9)
        {
            temp=0.2;
        }
    
        Dpwm0Regs.DPWMEV1.all = temp*PERIOD;
    
    //    Dpwm0Regs.DPWMINT.bit.PRD = 0;   //clear the flag
        Uint32 read_scrap;
        read_scrap = Dpwm3Regs.DPWMINT.bit.PRD;
    }
    

  • #define MAIN 1

    #include "system_defines.h"
    #include "Cyclone_Device.h"
    #include "pmbus_commands.h"
    #include "pmbus_common.h"
    #include "pmbus_topology.h"
    #include "variables.h"
    #include "functions.h"
    #include "software_interrupts.h"
    #include "cyclone_defines.h"
    #include "stdio.h"

    #define PCLK_PERIOD 4.0e-9
    #define PERIOD_SECONDS 10.0e-6
    #define PERIOD ((int)(PERIOD_SECONDS/PCLK_PERIOD)<<4)
    #define EVENT1 (int)(PERIOD*0.2)

    Uint32 FAULTMUXINTSTAT_value;
    float temp= 0.2;

    void init_dpwm0(void)
    {
    Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 0; // disable DPWM0 locally during initilization

    Dpwm0Regs.DPWMCTRL0.bit.CLA_EN = 0; // default is 1 (i.e. default is to use the filter output to control DPWM)

    Dpwm0Regs.DPWMPRD.all = PERIOD; // use .all for all values, so that the scaling matches
    Dpwm0Regs.DPWMEV1.all = EVENT1; // set EVENT 1 to 0% (start) of period

    Dpwm0Regs.DPWMINT.bit.PRD_INT_EN = 1; //open DPWM0 interrupt
    Dpwm0Regs.DPWMINT.bit.PRD_INT_SCALE = 0010; //Period Interrupt generated once every 4 switching cycles

    // CimRegs.FIRQPR.bit.FIRQ_DPWM0 = 1; // set to FIQ mode

    //Disable interrupts
    disable_interrupt();
    disable_fast_interrupt();
    //This is necessary to make sure all interrupt status values are
    //cleared. Added here by ZCS feature
    FAULTMUXINTSTAT_value = FaultMuxRegs.FAULTMUXINTSTAT.all;
    //Configure IRQ
    write_reqmask(CIMINT_ALL_DPWM0 | CIMINT_ALL_FAULT_MUX);
    //Configure FIQ
    write_firqpr(CIMINT_ALL_DPWM0 | CIMINT_ALL_FAULT_MUX);
    // Enable interrupts
    enable_fast_interrupt();
    enable_interrupt();

    Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 1; // enable DPWM0 locally
    LoopMuxRegs.GLBEN.bit.DPWM0_EN = 1; // enable DPWM0 globally
    }


    void main()
    {

    if(GioRegs.FAULTIN.bit.FLT3_IN == 0)
    {
    clear_integrity_word();
    }

    init_pmbus(0x58); // initialize PMBus handler

    init_dpwm0(); // initialize DPWM0

    //This is necessary to make sure all interrupt status values are
    //cleared.
    FAULTMUXINTSTAT_value = FaultMuxRegs.FAULTMUXINTSTAT.all;

    for(;;)
    {
    pmbus_handler();
    }
    }


    //#pragma INTERRUPT(c_int00,RESET)
    void c_int00(void)
    {
    main();
    }

    #pragma INTERRUPT(ADCValueGet,IRQ)
    void ADCValueGet(void)
    {

    temp=temp+0.01;
    if(temp>0.9)
    {
    temp=0.2;
    }

    Dpwm0Regs.DPWMEV1.all = temp*PERIOD;

    // Dpwm0Regs.DPWMINT.bit.PRD = 0; //clear the flag
    Uint32 read_scrap;
    read_scrap = Dpwm3Regs.DPWMINT.bit.PRD;
    }

  • The first statement enables DPWM0 interrupt at CIM level.

    The Second section of the code enables the interrupt at ARM7 level.

    Please refer to UCD3138 technical reference manual for more details on how to enable interrupt.

    I believe what happens in your case is that PMBus handler in main loop is not getting any execution time share.

    You probably do not clear the DPWM0 interrupt flag at the end of your fast interrupt, therefore your fast interrupt getting invoked as soon as ISR ends.

    This way the fast interrupt does not letting any lower priority tasks such as PMBus handler to execute.

    You need to clear your interrupt flag at the end of your interrupt service routine.

    Hope this makes sense.

    Please also ask a single question per post, so the post will be useful for other peoples reference.

    Regards,

  • Thank you so much.

    Your answer helps me a lot. According to the technical reference manual, now I know that 

     CimRegs.FIRQPR.bit.FIRQ_DPWM0 = 1; // set to FIQ mode

    cannot be introduced in user mode. So if I want to change the value of register CIM, It must be mortified in a privileged mode like this:

    //Configure IRQ
    write_reqmask(CIMINT_ALL_DPWM0);
    //Configure FIQ
    write_firqpr(CIMINT_ALL_DPWM0);

    However, my code still cannot work. 

     Is interrupt flag is a clear on read register? 

    In my code, I tried those two sentences to clear the interrupt flage, respectively. But they cannot solve my problem. 

    1.  read_scrap = Dpwm0Regs.DPWMINT.bit.PRD;  // Clear on read

    2.  Dpwm0Regs.DPWMINT.bit.PRD = 0; //clear the flag

    The result is still:


    I have been working on this problem for one week, and the deadline is coming. Would you please tell me the specific code directly to solve this problem. Thank you very very very much!! 

    There is my lasted code:

    #define MAIN 1

    #include "system_defines.h"
    #include "Cyclone_Device.h"
    #include "pmbus_commands.h"
    #include "pmbus_common.h"
    #include "pmbus_topology.h"
    #include "variables.h"
    #include "functions.h"
    #include "software_interrupts.h"
    #include "cyclone_defines.h"
    #include "stdio.h"

    #define PCLK_PERIOD 4.0e-9
    #define PERIOD_SECONDS 10.0e-6
    #define PERIOD ((int)(PERIOD_SECONDS/PCLK_PERIOD)<<4)
    #define EVENT1 (int)(PERIOD*0.2)

    Uint32 FAULTMUXINTSTAT_value;
    float temp= 0.2;

    void init_dpwm0(void)
    {
    Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 0; // disable DPWM0 locally during initilization
    Dpwm0Regs.DPWMCTRL0.bit.CLA_EN = 0; // default is 1 (i.e. default is to use the filter output to control DPWM)

    Dpwm0Regs.DPWMPRD.all = PERIOD; // use .all for all values, so that the scaling matches
    Dpwm0Regs.DPWMEV1.all = EVENT1; // set EVENT 1 to 0% (start) of period
    Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 1; // enable DPWM0 locally
    LoopMuxRegs.GLBEN.bit.DPWM0_EN = 1; // enable DPWM0 globally

    Dpwm0Regs.DPWMINT.bit.PRD_INT_EN = 1; //open DPWM0 interrupt
    Dpwm0Regs.DPWMINT.bit.PRD_INT_SCALE = 0010; //Period Interrupt generated once every 4 switching cycles


    //Disable interrupts
    disable_interrupt();
    disable_fast_interrupt();
    //Configure IRQ
    write_reqmask(CIMINT_ALL_DPWM0);
    //Configure FIQ
    write_firqpr(CIMINT_ALL_DPWM0);
    // Enable interrupts
    enable_fast_interrupt();
    enable_interrupt();

    }


    void main()
    {

    if(GioRegs.FAULTIN.bit.FLT3_IN == 0)
    {
          clear_integrity_word();
    }

    init_pmbus(0x58); // initialize PMBus handler
    init_dpwm0(); // initialize DPWM0

    //This is necessary to make sure all interrupt status values are
    //cleared.
    FAULTMUXINTSTAT_value = FaultMuxRegs.FAULTMUXINTSTAT.all;

      for(;;)
      {
        pmbus_handler();
      }
    }


    //#pragma INTERRUPT(c_int00,RESET)
    void c_int00(void)
    {
       main();
    }

    #pragma INTERRUPT(ADCValueGet,IRQ)
    void ADCValueGet(void)
    {
       register int32 fiq_number, interrupt_bits;
       volatile Uint32 read_scrap;
       fiq_number = CimRegs.FIQIVEC.all; // Clear on read
       if(fiq_number == 29) //DPWM0 interrupt
       {
          temp=temp+0.01;
          if(temp>0.9)
          {
             temp=0.2;
          }

          Dpwm0Regs.DPWMEV1.all = temp*PERIOD;
    }
          read_scrap = Dpwm0Regs.DPWMINT.bit.PRD;

         // Dpwm0Regs.DPWMINT.bit.PRD = 0; //clear the flag

    }

  • Hello,

    You are having floating point arithmetic in your fast interrupt that is called every 6 micro seconds.

    Floating point multiplication is a very time consuming operation and there isn't enough of MIPS in ARM7 in order to do this every 6 micro second.

    You should reduce your ISR execution time significantly and use shifts for division of your period instead.

    PMBus does not work because the ISR takes all the MIPS/Time.

    Hope this makes sense.

    Regards,

  • Thanks for your fast reply.

    Now I change the Period Interrupt generated once every 256 switching cycles

    Dpwm0Regs.DPWMINT.bit.PRD_INT_SCALE = 1111; //Period Interrupt generated once every 256 switching cycles

    And in ISR, I dd nothing but this:

    #pragma INTERRUPT(ADCValueGet,IRQ)
    void ADCValueGet(void)
    {

    temp++; // Uint32 temp=100
    if(temp>2000)
    {
    temp=100;
    }

    Dpwm0Regs.DPWMEV1.all = temp;

    Dpwm0Regs.DPWMINT.bit.PRD = 0; //clear the flag

    }

    However, the problem is still reapear. Could you please download this code in your board and have a try? I don't know whether there is something wrong with the .h files although there is no error during my compile.

    Thank you so much!!

  • Hello Yang Chen,


    Regarding the interrupt flag bit clearing at the end of ISR , instead of "Dpwm0Regs.DPWMINT.bit.PRD = 0;" please use:

    Dpwm0Regs.DPWMINT.bit.PRD_INT_EN = 1; //clear interrupt flag

    This causes a read from the DPWMINT register and will clear the PRD (Read only) bit.

    I promise you that if this does not resolve your issue, I will debug the code accordingly.

    Regards,

  • Thanks for your kindly reply. I change the sentence as you say. But...The problem is still

    The following files are my main.c and my .x0 file.

    Could you please try to download the .x0 file to your board or generate the .x0 file yourself with my main.c file? 

    Thank you so much. I really could not find where the problem is...(Cry)

  • #define MAIN 1

    #include "system_defines.h"
    #include "Cyclone_Device.h"
    #include "pmbus_commands.h"
    #include "pmbus_common.h"
    #include "pmbus_topology.h"
    #include "variables.h"
    #include "functions.h"
    #include "software_interrupts.h"
    #include "cyclone_defines.h"
    #include "stdio.h"

    #define PCLK_PERIOD 4.0e-9
    #define PERIOD_SECONDS 10.0e-6
    #define PERIOD ((int)(PERIOD_SECONDS/PCLK_PERIOD)<<4)
    #define EVENT1 (int)(PERIOD*0.2)

    Uint32 FAULTMUXINTSTAT_value;
    Uint32 temp= 100;

    void init_dpwm0(void)
    {
    Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 0; // disable DPWM0 locally during initilization
    Dpwm0Regs.DPWMCTRL0.bit.CLA_EN = 0; // default is 1 (i.e. default is to use the filter output to control DPWM)

    Dpwm0Regs.DPWMPRD.all = PERIOD; // use .all for all values, so that the scaling matches
    Dpwm0Regs.DPWMEV1.all = EVENT1; // set EVENT 1 to 0% (start) of period
    Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 1; // enable DPWM0 locally
    LoopMuxRegs.GLBEN.bit.DPWM0_EN = 1; // enable DPWM0 globally

    Dpwm0Regs.DPWMINT.bit.PRD_INT_EN = 1; //open DPWM0 interrupt
    Dpwm0Regs.DPWMINT.bit.PRD_INT_SCALE = 1111; //Period Interrupt generated once every 4 switching cycles


    //Disable interrupts
    disable_interrupt();
    disable_fast_interrupt();
    //Configure IRQ
    write_reqmask(CIMINT_ALL_DPWM0);
    //Configure FIQ
    write_firqpr(CIMINT_ALL_DPWM0);
    // Enable interrupts
    enable_fast_interrupt();
    enable_interrupt();

    }


    void main()
    {

    if(GioRegs.FAULTIN.bit.FLT3_IN == 0)
    {
    clear_integrity_word();
    }

    init_pmbus(0x58); // initialize PMBus handler
    init_dpwm0(); // initialize DPWM0


    for(;;)
    {
    pmbus_handler();
    }
    }


    #pragma INTERRUPT(c_int00,RESET)
    void c_int00(void)
    {
    main();
    }

    #pragma INTERRUPT(ADCValueGet,FIQ)
    void ADCValueGet(void)
    {
    temp++; // Uint32
    if(temp>2000)
    {
    temp=100;
    }

    Dpwm0Regs.DPWMEV1.all = temp;

    Dpwm0Regs.DPWMINT.bit.PRD_INT_EN = 1; //clear interrupt flag

    }

  • The system indicates that I cannot upload the .x0 file. Sorry.

  • Hi

    Please use:

    #pragma INTERRUPT(fast_interrupt,FIQ)
    void fast_interrupt(void)

     

    instead of:

     #pragma INTERRUPT(ADCValueGet,FIQ)
    void ADCValueGet(void)

    and make sure your FLT3 pin is kept high.

    I has compiled similar firmware and no issues found.

    Regards,

  • Thank you so much. You really save my life!

    I try to use 

    #pragma INTERRUPT(fast_interrupt,FIQ)
    void fast_interrupt(void)

    in my main.c

    But, it indicates that fast_interrupt function has been defined in interrupt.c. So I add my code in interrupt.c. Now the code can work as I want. 

    Thank you!