Part Number: TMS320F28P659DK-Q1
Other Parts Discussed in Thread: C2000WARE
I'm migrating my ECU project from an F28377D to an F28P659,
but the capture and AD sometimes work and sometimes don't,
depending on the order in which the CPUs enter the debugger,
and also in standalone mode. I tried changing the boot sequences,
initialization orders, and locks to start the CPUs, but without success.
I don't feel confident in this new microcomputer.
I would like the manufacturer to explain the initialization sequence,
so I have no doubt that the peripheral will work as programmed.
Here is the sequence I used in main, CPU1, and CPU2:
//
// Main CPU1
//
void main(void)
{
//
// Initialize device clock and peripherals
//
InitSysCtrl();
InitPeripheralClocks();
Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, DEVICE_FLASH_WAITSTATES);
DINT; // Disable CPU interrupts
InitPieCtrl(); // Initialize the PIE control registers to their default state
IER = 0x0000; // Disable CPU interrupts
IFR = 0x0000; // Clear all CPU interrupt flags:
InitPieVectTable(); // Initialize the PIE vector table
EALLOW;
DevCfgRegs.CPUSEL0.bit.EPWM1 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM2 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM3 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM4 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM5 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM6 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM7 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM8 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM9 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM10 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM11 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM12 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM13 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM14 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM15 = 1;
DevCfgRegs.CPUSEL0.bit.EPWM16 = 1;
DevCfgRegs.CPUSEL11.bit.ADC_A = 1;
DevCfgRegs.CPUSEL11.bit.ADC_B = 1;
DevCfgRegs.CPUSEL11.bit.ADC_C = 1;
DevCfgRegs.CPUSEL1.bit.ECAP1 = 1;
DevCfgRegs.CPUSEL1.bit.ECAP2 = 1;
EDIS;
//
// Transfer ownership of EPWM1 and ADCA to CPU02
//
EALLOW;
// To CPU2 from FLASH
// Give Memory Access to Flash Bank 3 and 4, Tab Table 3-454 pg 714, spruiz1.pdf
//
DevCfgRegs.BANKMUXSEL.bit.BANK3 = 0x3; // 11: Flash Bank is allowed to access from CPU2.
DevCfgRegs.BANKMUXSEL.bit.BANK4 = 0x3; // 11: Flash Bank is allowed to access from CPU2.
//DevCfgRegs.CPU2RESCTL.all = 0xA5A50001; // CPU2 is held in reset, Tab 3-510 pg 782, spruiz1.pdf
//
// Give Memory Access to GS.. SARAM to CPU02, Tab 3-541 pg 838, spruiz1a.pdf
//
MemCfgRegs.GSxMSEL.bit.MSEL_GS0 = 1; // 1: CPU2 is controller for this memory.
MemCfgRegs.GSxMSEL.bit.MSEL_GS1 = 0; // 0: CPU1 is controller for this memory.
MemCfgRegs.GSxMSEL.bit.MSEL_GS2 = 0; // 0: CPU1 is controller for this memory.
MemCfgRegs.GSxMSEL.bit.MSEL_GS3 = 1; // 1: CPU2 is controller for this memory.
MemCfgRegs.GSxMSEL.bit.MSEL_GS4 = 1; // 1: CPU2 is controller for this memory.
//DevCfgRegs.CPU2RESCTL.all = 0xA5A50000; // CPU2 reset is deactivated, Tab 3-510 pg 782, spruiz1.pdf
EDIS;
//
// Initialize GPIO and configure the GPIO pin as a push-pull output
//
Device_initGPIO();
SetupInputXBAR5(); // Setup the ADCs sync.
Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCACK.all = 0xFFFFFFFF; //IPCRtoLFlagAcknowledge(IPC_FLAG_ALL);
DELAY_US(100);
//
// to CPU2 from FLASH
//
Device_bootCPU2(BOOTMODE_BOOT_TO_FLASH_BANK3_SECTOR0);
// Setup only the GP I/O for SPI functionality
// This function is found in F2837xD_Spi.c
//
InitSpiGpio();
//
// Initialize the Device Peripheral.
//
InitCpuTimers(); // This function initializes the Cpu Timers.
InitSpi(); // This function initializes the SPI(s) to a known state.
//InitEPwm(); // This function initializes the EPwm(s) to a known state. (CPU2 only)
InitECapGpio(); // This function initializes the eCAP(s) IO to a known state.
//InitECap(); // This function initializes the eCAP(s) IO to a known state.
InitSci(); // This function initializes the SCI(s) to a known state.
//ConfigureADC(); // Configure the ADCs and power them up.
//SetupADCSoftwareSync(); // Setup the ADCs for software conversions.
//SetupInputXBAR5(); // Setup the ADCs sync.
//
// Configure CPU-Timer 0, 1, and 2 to interrupt every second:
// 200MHz CPU Freq, 1 second Period (in uSeconds)
//
ConfigCpuTimer(&CpuTimer0, 200, 400); // Read ADC.
ConfigCpuTimer(&CpuTimer1, 200, 1000); // Time Base. Timer for Datalogger.
ConfigCpuTimer(&CpuTimer2, 200, 50);//125); // Buzzer.
CpuTimer1Regs.PRD.all = 0xFFFFFFFF; // Free run for datalogger.
//
// To ensure precise timing, use write-only instructions to write to the
// entire register. Therefore, if any of the configuration bits are changed in
// ConfigCpuTimer and InitCpuTimers (in F2837xS_cputimervars.h), the below
// settings must also be updated.
//
CpuTimer0Regs.TCR.all = 0x4000;
CpuTimer1Regs.TCR.all = 0x4000;
CpuTimer2Regs.TCR.all = 0x4000;
//
// Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
// which is connected to CPU-Timer 1, and CPU int 14, which is connected
// to CPU-Timer 2:
//
IER |= M_INT1;
IER |= M_INT4;
IER |= M_INT8;
IER |= M_INT9;
IER |= M_INT11;
IER |= M_INT13;
IER |= M_INT14;
//
// Enable TINT0 in the PIE: Group 1 interrupt 7
//
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
//
// Enable eCAP1 INTn in the PIE: Group 4 interrupt 1
//
//PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
//
// Enable eCAP2 INTn in the PIE: Group 4 interrupt 2
//
//PieCtrlRegs.PIEIER4.bit.INTx2 = 1;
//
// Enable eCAP3 INTn in the PIE: Group 4 interrupt 3
//
PieCtrlRegs.PIEIER4.bit.INTx3 = 1;
//
// Enable eCAP4 INTn in the PIE: Group 4 interrupt 4
//
PieCtrlRegs.PIEIER4.bit.INTx4 = 1;
////
//// Enable eCAP5 INTn in the PIE: Group 4 interrupt 5
////
// PieCtrlRegs.PIEIER4.bit.INTx5 = 1;
//
// Enable eCAP6 INTn in the PIE: Group 4 interrupt 6
//
PieCtrlRegs.PIEIER4.bit.INTx6 = 1;
//
// Enable SCI-A RX INTn in the PIE: Group 9 interrupt 1
//
PieCtrlRegs.PIEIER9.bit.INTx1 = 1;
//
// Enable SCI-A TX INTn in the PIE: Group 9 interrupt 2
//
PieCtrlRegs.PIEIER9.bit.INTx2 = 1;
//
// Enable SCI-B RX INTn in the PIE: PIE Group 8 interrupt 3
//
PieCtrlRegs.PIEIER9.bit.INTx3 = 1;
//
// Enable SCI-B TX INTn in the PIE: Group 8 interrupt 4
//
PieCtrlRegs.PIEIER9.bit.INTx4 = 1;
PieCtrlRegs.PIEIER1.bit.INTx14 = 1; // IPC1 ISR
Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCACK.all = 0xFFFFFFFF;
DELAY_US(5000);
Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCSET.bit.IPC8 = 1; // Inform CPU2
while(!Cpu1toCpu2IpcRegs.CPU2TOCPU1IPCSTS.bit.IPC9); // Wait for CPU2 to set IPC9 //Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCFLG.bit.IPC9;
Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCACK.bit.IPC9 = 1;
//
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
EINT;
ERTM;
gBufferEEProm.GRAM.VAR.TPS_Cal = 1;
LoadBufferToCPU2();
IPCLtoRFlagSet(IPC_FLAG10);
//GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
//DELAY_US(1000 * 500); // ON delay
Init();
//
// Loop Forever
//
for(;;)
{
/**/
//
// Main CPU2
//
void main(void)
{
InitSysCtrl(); // Initialize System Control:
//DisablePeripheralClocks();
DINT; // Disable CPU interrupts
InitPieCtrl(); // Initialize the PIE control registers to their default state
IER = 0x0000; // Disable CPU interrupts
IFR = 0x0000; // Clear all CPU interrupt flags:
InitPieVectTable(); // Initialize the PIE vector table
//Tab 3-9 pg 178, spruiz1.pdf
DELAY_US(100);
//
// Wait until Shared RAM is available.
//
DELAY_US(10000);
while((MemCfgRegs.GSxMSEL.bit.MSEL_GS0 != 1) ||
(MemCfgRegs.GSxMSEL.bit.MSEL_GS3 != 1) ||
(MemCfgRegs.GSxMSEL.bit.MSEL_GS4 != 1))
{
}
IPCLtoRFlagSet(IPC_FLAG9); // Inform CPU1
while(IPCRtoLFlagBusy(IPC_FLAG8) == 0); // Wait for CPU1 to set IPC8
IPCRtoLFlagAcknowledge(IPC_FLAG8);
//while(IPCLtoRFlagBusy(IPC_FLAG9));
//
// Step 4. Initialize the Device Peripheral. This function can be
// found in F2837xS_CpuTimers.c
//
InitCpuTimers(); // This function initializes the Cpu Timers.
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
InitEPwm(); // This function initializes the EPwm(s) to a known state.
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
//InitECap(); // This function initializes the eCAP(s) IO to a known state.
//ConfigureADC();//InitADC(); // Configure the ADCs and power them up.
//SetupADCSoftwareSync(); // Setup the ADCs for software conversions.
//
// Configure CPU-Timer 0, 1, and 2 to interrupt every second:
// 200MHz CPU Freq, 1 second Period (in uSeconds)
//
//ConfigCpuTimer(&CpuTimer0, 200, 400); // Free run for Fast Squirt.
CpuTimer0Regs.TCR.bit.FREE = 1; // Timer Free Run Enabled
CpuTimer0Regs.TCR.bit.TIE = 0; // 0 = Disable/ 1 = Enable Timer Interrupt
//CpuTimer0Regs.TIM.all // Counter.
//
// Reset interrupt counter:
//
CpuTimer0.InterruptCount = 0;
ConfigCpuTimer(&CpuTimer1, 200, 1000); // Time Base. Timer for Datalogger.
ConfigCpuTimer(&CpuTimer2, 200, 125); // Buzzer.
//
// To ensure precise timing, use write-only instructions to write to the
// entire register. Therefore, if any of the configuration bits are changed in
// ConfigCpuTimer and InitCpuTimers (in F2837xD_cputimervars.h), the below
// settings must also be updated.
//
CpuTimer0Regs.TCR.all = 0x4040;
CpuTimer1Regs.TCR.all = 0x4000;
CpuTimer2Regs.TCR.all = 0x4000;
//
// Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
// which is connected to CPU-Timer 1, and CPU int 14, which is connected
// to CPU-Timer 2:
//
IER |= M_INT1;
IER |= M_INT3;
IER |= M_INT4;
//IER |= M_INT9;
IER |= M_INT11;
IER |= M_INT13;
IER |= M_INT14;
//
// 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;
PieCtrlRegs.PIEIER3.bit.INTx4 = 1;
PieCtrlRegs.PIEIER3.bit.INTx5 = 1;
PieCtrlRegs.PIEIER3.bit.INTx6 = 1;
PieCtrlRegs.PIEIER3.bit.INTx7 = 1;
PieCtrlRegs.PIEIER3.bit.INTx8 = 1;
PieCtrlRegs.PIEIER3.bit.INTx9 = 1;
PieCtrlRegs.PIEIER3.bit.INTx10 = 1;
PieCtrlRegs.PIEIER3.bit.INTx11 = 1;
PieCtrlRegs.PIEIER3.bit.INTx12 = 1;
PieCtrlRegs.PIEIER3.bit.INTx13 = 1;
PieCtrlRegs.PIEIER3.bit.INTx14 = 1;
PieCtrlRegs.PIEIER3.bit.INTx15 = 1;
PieCtrlRegs.PIEIER3.bit.INTx16 = 1;
//
// Enable TINT0 in the PIE: Group 1 interrupt 7
//
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
//
// Enable eCAP1 INTn in the PIE: Group 4 interrupt 1
//
PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
//
// Enable eCAP2 INTn in the PIE: Group 4 interrupt 2
//
PieCtrlRegs.PIEIER4.bit.INTx2 = 1;
//
// Enable eCAP5 INTn in the PIE: Group 4 interrupt 5
//
// PieCtrlRegs.PIEIER4.bit.INTx5 = 1;
//
// Enable eCAP6 INTn in the PIE: Group 4 interrupt 6
//
// PieCtrlRegs.PIEIER4.bit.INTx6 = 1;
//
// Enable SCIRXINTA INTn in the PIE: Group 9 interrupt 1
//
// PieCtrlRegs.PIEIER9.bit.INTx1 = 1;
//
// Enable SCITXINTA INTn in the PIE: Group 9 interrupt 2
//
// PieCtrlRegs.PIEIER9.bit.INTx2 = 2;
//
// Enable global Interrupts and higher priority real-time debug events:
//
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
InitECap();
ConfigureADC(); // Configure the ADCs and power them up.
SetupADCSoftwareSync(); // Setup the ADCs for software conversions.
EINT;
ERTM;
//gTimerPOR = TIME_POR;
gWriteBufferC2.ECU2Ready = 0;
gFlagPOR_IG = 1;
//
// Loop Forever
//
for(;;)
{
/**/
best regards.
Marcelo.