Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
CaptCompISR freezes PPMAC
#1
I've taken the example of the Capture Interrupt Routine from the manual in order to try and capture the encoder count on a channel that is being used as the external time-base. The idea is to latch the encoder count on an accurate tick. I'm using the USER flag input on Chan[2] of an ACC24E3[1].
I have tested that the external time-base and triggering work as expected - the problem is that whenever I enable the ISR and send the tick the PMAC CPU locks up.

The code is shown below and is almost the same as the manual. I also set Acc24E3[1].IntCtrl = $40000 //Chan[2].PosCapt

Code:
void CaptCompISR (void)
{
    volatile GateArray3 *TickGate3IC; //ASIC structure pointer
    int *CaptCounter; //Logs number of ticks
    int *CaptPosStore; //Storage pointer
    
    TickGate3IC = GetGate3MemPtr(1); //Pointer to IC base
    CaptCounter = (int *)pushm + 65535; // Sys.Idata[65535]
    CaptPosStore = (int *)pushm + *CaptCounter + 65536;
    *CaptPosStore = TickGate3IC->Chan[2].HomeCapt; //Store position
    (*CaptCounter)++; //Increment Counter
    TickGate3IC->IntCtrl = 0x04; //Clear interrupt
}

Note that I am setting the tick by a simple switch that is pressed - I mention this incase there is a bounce issue.
Reply
#2
I can look into this on Monday.
Reply
#3
I have verified your issue. I also experience a crash when running basically the User Manual's ISR code. I will look into why this occurs.

This is what I have found so far:

If I run the following code, I do not experience a crash upon setting the HOME flag high:

Code:
void CaptCompISR (void)
{
    volatile GateArray3 *MyFirstGate3IC; // ASIC structure pointer
    MyFirstGate3IC = GetGate3MemPtr(0); // Pointer to IC base
    MyFirstGate3IC->IntCtrl = 1; // Clear interrupt source

}

But when I try to modify something else in the gate, or change a P-Variable, it crashes; for example:

Code:
void CaptCompISR (void)
{

    volatile GateArray3 *MyFirstGate3IC; // ASIC structure pointer
        MyFirstGate3IC = GetGate3MemPtr(0); // Pointer to IC base
    MyFirstGate3IC->IntCtrl = 1; // Clear interrupt source
    MyFirstGate3IC->Chan[1].CompA++; // This line causes the ISR to crash
    //pshm->P[1]++; // Using this will crash also
}

Something else you may want to double check is whether you have placed the ISR code correctly into usrcode.c and selected "Compile" as its build option in usrcode.c's Properties.

Also, verify that you do not have Gate3[i].Chan[j].Equ high, as this can also trigger the ISR, confounding our issue. You can ensure that Equ never goes high by doing something like this in a PLC:

Code:
open plc 2
local NetPos;
NetPos = Gate3[0].Chan[0].PhaseCapt*16
Gate3[0].Chan[0].CompA=NetPos+10000.0
Gate3[0].Chan[0].CompB=NetPos-20000.0

while(1>0)
{
Gate3[0].Chan[0].CompA=NetPos+10000.0
Gate3[0].Chan[0].CompB=NetPos+5000.0
}

close

I'll see if I can figure out why the ISR is behaving like this, though.
Reply
#4
Hi,

Additional information:

You need to add this to usrcode.h:

Code:
void CaptCompISR(void);
EXPORT_SYMBOL(CaptCompISR);

Otherwise, the function will not be mapped properly and it will crash the system. This is most likely your problem.

Can you please verify and post whether this solves your issue?
Reply
#5
Hi,

Yes I can confirm that I have the prototype in the header file and that the usrcode.c is set to compile. (usrcode.h is set to Content but I think that's correct).

I can also confirm that the ISR does indeed work if you are not writing to a variable. I can also clear the PosCapt flag with a TickGate3IC->Chan[2].HomeCapt without the PMAC freezing

I'm checking the equ status, however, I'm assuming the ISR should not interrupt unless the relevant bit in IntCtrl (23-16) are set.
Reply
#6
As an update I can confirm that the following works ok but as soon as you try and address the P variable the ISR hangs

Code:
void CaptCompISR (void)
{
    volatile GateArray3 *TickGate3IC; //ASIC structure pointer
    int *CaptCounter; //Logs number of ticks
    int *CaptPosStore; //Storage pointer
    
    TickGate3IC = GetGate3MemPtr(1); //Pointer to IC base
    CaptCounter = (int *)pushm + 0; // Sys.Idata[0]
    CaptPosStore = (int *)pushm + 1;
    (*CaptCounter)++; //Increment Counter
    *CaptPosStore = TickGate3IC->Chan[2].HomeCapt;
    //pshm->P[1]++; //This is the thing that crashes!!!
    TickGate3IC->IntCtrl = 0x04; //Clear interrupt
}
Reply
#7
Hi tweekzilla,

I apologize for not mentioning this before:

You cannot use floating-point math of any kind in the ISR. You can only use integer types. Thus, using a P-Variable would cause the ISR not to work.
Reply
#8
Hi, I have the problem that while my program is running the ISR freezes on random occasions. My Program consists of a motion from a) to b) getting repeated as many times as I like.
While the motor is jogging to position a) I have the CaptCompISR logging the position. The purpose of it is to check if the Motor was on the position corresponding to the number of the trigger that launches the ISR and then to induce a position correction if it isn't.
The position correction is calculated and induced by the custom phase algorithm assigned to Motor[0] while the Motion is carried out by Motor[1].
At first I had the code for storing the captured positon inside the ISR but moved it to the phasealgorithm in order to exclude it as a cause for the error and now moved back again.
I also made sure I had nothing else but "int"-variables in the ISR. If I iterate the motion loop 500 times the ISR freezes at least 2 to 3 times. I can get it to work again by reading the "Gate3[0].Chan[0].HomeCapt" register from the terminal. I guess why this is happening is that the "Gate3[0].Chan[0].Equ" bit turns high. Though the ISR does not always freeze when it turns high, every time it freezes the bit is high. So I added some lines of code out of the Equ Compare example featured in the User's Manual which forces the Equ-State to zero. This had no effect on the freezing of the ISR. The only thing that makes my ISR restart automatically is to read the "Gate3[0].Chan[0].HomeCapt"-Register from a plc. This too is not perfect because my Motion seems to sometimes stop for 1/10 up to 5/10 of a second at the end of the move or just after having reached the starting position again, sometimes several times a row. Then again it runs smooth without pausing. I tried deactivating the Equ State inside the ISR and inside the plc but without effect. I had a plc runnning the code the guy posted above for making sure the Equ-state does not turn high, but that too did not have an effect. Does anyone have some further info on that? This is the code I have in my ISR:

void CaptCompISR(void)
{

int MyFirstGate3Adr = pshm->OffsetGate3[0] ;

volatile int *MyFirstGate3IntCtrl = NULL ; // InCtrl direct register pointer declaration
MyFirstGate3IntCtrl = ( unsigned int * ) piom + ( ( MyFirstGate3Adr + 0x224 ) >> 2 ) ; // IntCtrl register adress calculation 4bytes Per Word


// Deactivate ISR
*MyFirstGate3IntCtrl = !( *MyFirstGate3IntCtrl | 0xffff00ff ) ; // ( NOR - Operation ) 24 Bit - Bit Nr.16 has to be set to zero
*MyFirstGate3IntCtrl = *MyFirstGate3IntCtrl | 0x00000001 ; // Clear interrupt source

int *CaptCounter = NULL ; // Logs number of triggers
CaptCounter = (int *)pushm + 60200 ;

volatile int *MyFirstGate3HomeCapt = NULL ; // HomeCapt direct register pointer declaration
MyFirstGate3HomeCapt = ( unsigned int * ) piom + ( ( MyFirstGate3Adr + 0x74 ) >> 2 ) ; // HomeCapt register adress calculation

int *CaptPosStore = NULL ; // Storage pointer
CaptPosStore = (int *)pushm + *CaptCounter + 65000 ;

// Determine Shared Memory-Pointer Adresses
int *StartScan_C = NULL ; // Pointer zum setzen des Flags für den Start der Scan-Fahrt
StartScan_C = ( int * ) pushm + 60100 ;

int *PulseInt_C = NULL ; // Switch for executing correction in PhaseRoutine
PulseInt_C = ( int * ) pushm + 60101 ;
*PulseInt_C = 1 ;

int *IsrCheck_C = NULL ;
IsrCheck_C = ( int * ) pushm + 60221 ;

(*CaptCounter)++ ; // Increment counter, starts at 0

(*IsrCheck_C)++ ; // Checking variable

if ( *CaptCounter != 0 ) *StartScan_C = 1 ; // Prompt plc 7 to start motion
}
Reply
#9
I have an Update on my Issue. The ISR does not crash anymore if I do not reset certain UserSharedMemory registers at the end of the iterated
motion. I use UserAlgo.BgCplc[1] to reset the registers since I can not run through the register - adresses in while loop in plc programs. Is there maybe a concflict between the UserAlgo.BgCplc[1] and the ISR ? It seems odd to me that resetting these registers in the CPLC does have this effect. However the irregular pauses inbetween moves are still there. Maybe this too is caused by my two BgCplc - programs.
Reply
#10
Ok - after having removed the code resetting some flags including flags accessed by the ISR, the pausing only occurs at the end of the move when I export the data, which indicates that it are the BgCplc - programs causing the issues.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)