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.
I am unable to 'Flash' the code to a microcontroller (TMS320F28027) on PCB using XDS 110 Debug probe. The Micro-controller on the PCB is successfully programmed in RAM configuration. I have made the necessary changes (changing the .cmd file).
The same code works in 'Flash' mode when used on Launchpad (Launchxl-f28027F) using XDS 100V2 debug probe.
I have included the necessary .cmd file.
I have included the following lines:
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t) &RamfuncsLoadSize);
InitFlash();
The build settings are set as:
Here is the schematic of the debug connection for the board on PCB:
The code is a simple modification of 'Example_2802xEPwmDeadBand'.
//########################################################################### // // FILE: Example_2802xEpwmDeadBand.c // // TITLE: Check PWM deadband generation // // ASSUMPTIONS: // // This program requires the f2802x header files. // // Monitor ePWM1 - ePWM3 on an Oscilloscope as described // below. // // EPWM1A is on GPIO0 // EPWM1B is on GPIO1 // // EPWM2A is on GPIO2 // EPWM2B is on GPIO3 // // EPWM3A is on GPIO4 // EPWM3B is on GPIO5 // // As supplied, this project is configured for "boot to SARAM" // operation. The 2802x Boot Mode table is shown below. // For information on configuring the boot mode of an eZdsp, // please refer to the documentation included with the eZdsp, // // $Boot_Table // While an emulator is connected to your device, the TRSTn pin = 1, // which sets the device into EMU_BOOT boot mode. In this mode, the // peripheral boot modes are as follows: // // Boot Mode: EMU_KEY EMU_BMODE // (0xD00) (0xD01) // --------------------------------------- // Wait !=0x55AA X // I/O 0x55AA 0x0000 // SCI 0x55AA 0x0001 // Wait 0x55AA 0x0002 // Get_Mode 0x55AA 0x0003 // SPI 0x55AA 0x0004 // I2C 0x55AA 0x0005 // OTP 0x55AA 0x0006 // Wait 0x55AA 0x0007 // Wait 0x55AA 0x0008 // SARAM 0x55AA 0x000A <-- "Boot to SARAM" // Flash 0x55AA 0x000B // Wait 0x55AA Other // // Write EMU_KEY to 0xD00 and EMU_BMODE to 0xD01 via the debugger // according to the Boot Mode Table above. Build/Load project, // Reset the device, and Run example // // $End_Boot_Table // // // // DESCRIPTION: // // This example configures ePWM1, ePWM2 and ePWM3 for: // - Count up/down // - Deadband // // 3 Examples are included: // * ePWM1: Active low PWMs // * ePWM2: Active low complementary PWMs // * ePWM3: Active high complementary PWMs // // Each ePWM is configured to interrupt on the 3rd zero event // when this happens the deadband is modified such that // 0 <= DB <= DB_MAX. That is, the deadband will move up and // down between 0 and the maximum value. // // // View the EPWM1A/B, EPWM2A/B and EPWM3A/B waveforms // via an oscilloscope // // //########################################################################### // $TI Release: F2802x Support Library v230 $ // $Release Date: Fri May 8 07:43:05 CDT 2015 $ // $Copyright: Copyright (C) 2008-2015 Texas Instruments Incorporated - // http://www.ti.com/ ALL RIGHTS RESERVED $ //########################################################################### #include "DSP28x_Project.h" // Device Headerfile and Examples Include File // Prototype statements for functions found within this file. void InitEPwm1Example(void); void InitEPwm2Example(void); void InitEPwm3Example(void); __interrupt void epwm1_isr(void); __interrupt void epwm2_isr(void); __interrupt void epwm3_isr(void); // Global variables used in this example uint32_t EPwm1TimerIntCount; uint32_t EPwm2TimerIntCount; uint32_t EPwm3TimerIntCount; uint16_t EPwm1_DB_Direction; uint16_t EPwm2_DB_Direction; uint16_t EPwm3_DB_Direction; // Maximum Dead Band values #define EPWM1_MAX_DB 0x000A #define EPWM2_MAX_DB 0x03FF #define EPWM3_MAX_DB 0x000F //#define 0 #define EPWM1_MIN_DB 0x000A #define EPWM2_MIN_DB 0 #define EPWM3_MIN_DB 0x000F // To keep track of which way the Dead Band is moving #define DB_UP 1 #define DB_DOWN 0 #define phase 150 #define D 90 // The following pointer to a function call calibrates the ADC and internal oscillators #define Device_cal (void (*)(void))0x3D7C80 //#pragma CODE_SECTION(InitFlash, "ramfuncs"); //#pragma CODE_SECTION(&epwm1_isr, "ramfuncs"); //#pragma CODE_SECTION(&epwm2_isr, "ramfuncs"); //#pragma CODE_SECTION(&epwm3_isr, "ramfuncs"); /******************************************************************************/ // These are defined by the linker extern uint16_t RamfuncsLoadStart; extern uint16_t RamfuncsLoadSize; extern uint16_t RamfuncsRunStart; void main(void) { // WARNING: Always ensure you call memcpy before running any functions from RAM // InitSysCtrl includes a call to a RAM based function and without a call to // memcpy first, the processor will go "into the weeds" memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t) &RamfuncsLoadSize); InitFlash(); // #ifdef _FLASH // memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); // #endif // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the f2802x_SysCtrl.c file. InitSysCtrl(); // Step 2. Initialize GPIO: // This example function is found in the f2802x_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // Skipped for this example // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3 // These functions are in the f2802x_EPwm.c file InitEPwm1Gpio(); InitEPwm2Gpio(); InitEPwm3Gpio(); // 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 f2802x_PieCtrl.c file. InitPieCtrl(); // 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 f2802x_DefaultIsr.c. // This function is found in f2802x_PieVect.c. InitPieVectTable(); // Interrupts that are used in this example are re-mapped to // ISR functions found within this file. EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.EPWM1_INT = &epwm1_isr; PieVectTable.EPWM2_INT = &epwm2_isr; PieVectTable.EPWM3_INT = &epwm3_isr; EDIS; // This is needed to disable write to EALLOW protected registers // Step 4. Initialize all the Device Peripherals: // Not required for this example EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; EDIS; InitEPwm1Example(); InitEPwm2Example(); InitEPwm3Example(); EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; // Step 5. User specific code, enable interrupts // Initialize counters: EPwm1TimerIntCount = 0; EPwm2TimerIntCount = 0; EPwm3TimerIntCount = 0; // Enable CPU INT3 which is connected to EPWM1-3 INT: IER |= M_INT3; // Enable EPWM INTn in the PIE: Group 3 interrupt 1-3 PieCtrlRegs.PIEIER3.bit.INTx1 = 1; PieCtrlRegs.PIEIER3.bit.INTx2 = 1; PieCtrlRegs.PIEIER3.bit.INTx3 = 1; // Enable global Interrupts and higher priority real-time debug events: EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM // Step 6. IDLE loop. Just sit and loop forever (optional): for(;;) { __asm(" NOP"); } } __interrupt void epwm1_isr(void) { if(EPwm1_DB_Direction == DB_UP) { if(EPwm1Regs.DBFED < EPWM1_MAX_DB) { EPwm1Regs.DBFED++; EPwm1Regs.DBRED++; } else { EPwm1_DB_Direction = DB_DOWN; EPwm1Regs.DBFED--; EPwm1Regs.DBRED--; } } else { if(EPwm1Regs.DBFED == EPWM1_MIN_DB) { EPwm1_DB_Direction = DB_UP; EPwm1Regs.DBFED++; EPwm1Regs.DBRED++; } else { EPwm1Regs.DBFED--; EPwm1Regs.DBRED--; } } EPwm1TimerIntCount++; // Clear INT flag for this timer EPwm1Regs.ETCLR.bit.INT = 1; // Acknowledge this interrupt to receive more interrupts from group 3 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } __interrupt void epwm2_isr(void) { if(EPwm2_DB_Direction == DB_UP) { if(EPwm2Regs.DBFED < EPWM2_MAX_DB) { EPwm2Regs.DBFED++; EPwm2Regs.DBRED++; } else { EPwm2_DB_Direction = DB_DOWN; EPwm2Regs.DBFED--; EPwm2Regs.DBRED--; } } else { if(EPwm2Regs.DBFED == EPWM2_MIN_DB) { EPwm2_DB_Direction = DB_UP; EPwm2Regs.DBFED++; EPwm2Regs.DBRED++; } else { EPwm2Regs.DBFED--; EPwm2Regs.DBRED--; } } EPwm2TimerIntCount++; // Clear INT flag for this timer EPwm2Regs.ETCLR.bit.INT = 1; // Acknowledge this interrupt to receive more interrupts from group 3 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } __interrupt void epwm3_isr(void) { if(EPwm3_DB_Direction == DB_UP) { if(EPwm3Regs.DBFED < EPWM3_MAX_DB) { EPwm3Regs.DBFED++; EPwm3Regs.DBRED++; } else { EPwm3_DB_Direction = DB_DOWN; EPwm3Regs.DBFED--; EPwm3Regs.DBRED--; } } else { if(EPwm3Regs.DBFED == EPWM3_MIN_DB) { EPwm3_DB_Direction = DB_UP; EPwm3Regs.DBFED++; EPwm3Regs.DBRED++; } else { EPwm3Regs.DBFED--; EPwm3Regs.DBRED--; } } EPwm3TimerIntCount++; // Clear INT flag for this timer EPwm3Regs.ETCLR.bit.INT = 1; // Acknowledge this interrupt to receive more interrupts from group 3 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } void InitEPwm1Example() { EPwm1Regs.TBPRD = 200; // Set timer period 300 IS 100KHZ EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // is 0 EPwm1Regs.TBCTR = 0x0000; // Clear counter // Setup TBCLK EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable loading EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Setup compare EPwm1Regs.CMPA.half.CMPA = 100; //CHANGE DUTY // Set actions EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero EPwm1Regs.AQCTLB.bit.CAD = AQ_SET; // Active Low PWMs - Setup Deadband EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; EPwm1Regs.DBRED = EPWM1_MAX_DB ; EPwm1Regs.DBFED = EPWM1_MIN_DB ; EPwm1_DB_Direction = DB_UP; // Interrupt where we will change the band EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm1Regs.ETPS.bit.INTPRD = ET_DISABLE ; // Generate INT on 3rd event ET_DISABLE ET_3RD } void InitEPwm2Example() { /*EPwm2Regs.TBPRD = 300; // Set timer period EPwm2Regs.TBPHS.half.TBPHS = 150; // is 0 EPwm2Regs.TBCTR = 0x0000; // Clear counter // Setup TBCLK EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable loading EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4; // Clock ratio to SYSCLKOUT EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV4; // Slow just to observe on the scope // Setup compare EPwm2Regs.CMPA.half.CMPA = 3000; // Set actions EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM2A on Zero EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; EPwm2Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM2A on Zero EPwm2Regs.AQCTLB.bit.CAD = AQ_SET; // Active Low complementary PWMs - setup the band EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_LOC; EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL; EPwm2Regs.DBRED = EPWM2_MIN_DB; EPwm2Regs.DBFED = EPWM2_MIN_DB; EPwm2_DB_Direction = DB_UP; // Interrupt where we will modify the band EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm2Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event */ EPwm2Regs.TBPRD = 300; // Set timer period EPwm2Regs.TBPHS.half.TBPHS = 0x0000; // is 0 EPwm2Regs.TBCTR = 0x0000; // Clear counter // Setup TBCLK EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable loading EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; // Slow so we can observe on the scope EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Setup compare EPwm2Regs.CMPA.half.CMPA = D; // Set actions EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM3A on Zero EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; EPwm2Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM3A on Zero EPwm2Regs.AQCTLB.bit.CAD = AQ_SET; // Active high complementary PWMs - Setup the band EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL; EPwm2Regs.DBRED = 0; EPwm2Regs.DBFED = 0; EPwm2_DB_Direction = DB_UP; // Interrupt where we will change the deadband EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT //EPwm3Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event EPwm2Regs.ETPS.bit.INTPRD = ET_DISABLE; // Generate INT on 3rd event EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; //TBCLK = SYSCLKOUT EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; //set 1 } void InitEPwm3Example() { EPwm3Regs.TBCTL.bit.PHSDIR = TB_DOWN; //Count DOWN on sync EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW; EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; //Clock ratio to SYSCLKOUT EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm3Regs.TBPRD = 300; // Set timer period EPwm3Regs.TBPHS.half.TBPHS = 300; // phase is 0 EPwm3Regs.TBCTR = 0x0000; // Clear counter // Setup TBCLK EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Disable loading EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1; // Slow so we can observe on the scope // Setup compare EPwm3Regs.CMPA.half.CMPA = D; // Set actions EPwm3Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM3A on Zero EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR; EPwm3Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM3A on Zero EPwm3Regs.AQCTLB.bit.CAD = AQ_SET; // Active high complementary PWMs - Setup the deadband EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL; EPwm3Regs.DBRED = 0; EPwm3Regs.DBFED = 0; EPwm3_DB_Direction = DB_UP; // Interrupt where we will change the deadband EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm3Regs.ETSEL.bit.INTEN = 1; // Enable INT //EPwm3Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event EPwm3Regs.ETPS.bit.INTPRD = ET_DISABLE; // Generate INT on 3rd event } ==========================================================================
Please let me know how I can fix this issue.
Hi Ujjwal,
When you load the "flash" application to your custom board from CCS what does the failure look like: does CCS show errors? If not, once you load the application from CCS and issue a run from CCS does the application execute but not when you issue a reset? Please do provide additional details as that would help.
For Standalone execution from Flash please check that the Boot Mode selection pins are configured correctly. Please see section 2.2.9 of the TRM https://www.ti.com/lit/ug/sprui09/sprui09.pdf.
Thanks,
Ashwini
Hi Ashwini,
Thanks for a prompt response.
When I load the "flash" application to the custom board from CCS: CCS does not show errors. Once I load the application from CCS and issue a run from CCS- Yes, the application executes but not when I issue a reset.
The boot mode selection pins are configured in Standalone Boot Mode - GetMode:
boot mode selection pins are configured in hardware:
I couldn't read the value at 0x3D7FF in debug window to confirm that it flash (Error: Memory map prevented reading).
Hi Ujjwal,
I will sync up with the team on the boot mode configuration you have provided and get back to you.
Thanks,
Ashwini
Hello,
When I load the "flash" application to the custom board from CCS: CCS does not show errors. Once I load the application from CCS and issue a run from CCS- Yes, the application executes but not when I issue a reset.
The boot mode selection pins are configured in Standalone Boot Mode - GetMode:
Hello Ujjwal,
Is CCS connected, or the XDS100 connected, when trying to run from reset? If yes, then the device will be looking at the EMU boot options are set. (double check the state of TRSTn with a scope). In CCS you can set the emu boot mode via scripts -> emu boot mode select -> flash
Regards
Lori
Hi Lori,
1) While the CCS is connected (XDS 110), I tried scripts -> emu boot mode select -> flash
Once the CPU is 'reset'. The code runs successfully after I click 'resume'.
The code does not run once I disconnect CCS and power up the micro-controller on PCB.
When I use the same code and XDS 100v2 to program another launchpad-F28027F. The code runs once I disconnect CCS and power up the Launchpad.
2) I checked the state of the TRSTn pin on the oscilloscope:
Thank you for the details. Can you check the value in the memory location highlighted below? In your previous screenshot the address was not correct (0x3d7FF vs 0x3d7BFE)
Hi Lori,
Thanks for pointing out my mistake, here is what i observe:
0x3d7BFF: 0xFFFF
0x3d7BFE: 0xFFFF
I also checked
0x0D00: 0x55AA
0x0D01: 0x000B
Hi Lori and Ashwini,
I have resolved my issue. It was my mistake. The reason it was not working because I had a pull-down resistor at GPIO 34 instead of Pull-up (not shown in the schematic image posted above).
Thank you for the fast and effective response.