Unable to resolve else statement after assigning to a union

General discussion on mikroBasic PRO for dsPIC30/33 and PIC24.
Post Reply
Author
Message
EESL
Posts: 12
Joined: 04 Feb 2019 15:30

Unable to resolve else statement after assigning to a union

#1 Post by EESL » 22 Mar 2019 11:31

Hello
I have a strange behaviour in a part of my code:
I have defined a union which I use:

Code: Select all

 union manflg{
      struct  {
              unsigned reg  : 16;
      };
      struct  {
              unsigned ud1     : 1;
              unsigned macu    : 2; // macu Mando calculo
              unsigned ud2     : 11;
              unsigned tambor  : 2;
      };
      struct  {
              unsigned isactive   : 1;  //LSB
              unsigned fullrange  : 1;// if 1 then 0 - 5V range
              unsigned inverted   : 1; // if 1 then left is full
              unsigned remote     : 1;  // is remote controlled at the moment
              unsigned inparo     : 1;   // if 1 then Mando is in Paro --> relacionado a sus config!!
              unsigned b5         : 1;
              unsigned b6         : 1; 
              unsigned b7         : 1;
              unsigned b8         : 1;
              unsigned b9         : 1; 
              unsigned b10        : 1; 
              unsigned b11        : 1;
              unsigned b12        : 1;
              unsigned b13        : 1;
              unsigned tambitL    : 1;
              unsigned tambitH    : 1;
      };
};

union manflg MANDO12345FLG;

union manflg MANDOFLG[5];

what i would like to do is this:

Code: Select all

if(Dv_bol(fsdata[ADR_mando_active]) == 1) {
    MANDOFLG[i].isactive = fsdata[ADR_mando_active]; // after asigning here.. 
}else{   //...cant resolve this else statement
    errorocurred = 1;
}
after validating the data in fsdata[ADR_mando_active] assigning it to MANDOFLG.isactive.
that still works (i can see in the watch window) but when i am debugging it does not keep going on the else statement. it stops there or to be precise it does not resolve it. it is not frozen(not crashed) because i can pause the debugger with F6 and restart from there but it cant resolve the else statement.
what makes the whole thing really interesting is if i have this statement it works:

Code: Select all

if(Dv_bol(fsdata[ADR_mando_active]) == 1) {
    MANDO12345FLG.isactive = fsdata[ADR_mando_active];
}else{  //this one works fine
    errorocurred = 1;
}
and also this works fine:

Code: Select all

if(Dv_bol(fsdata[ADR_fullrecorido]) == 1) {
    MANDOFLG[i].fullrange = fsdata[ADR_fullrecorido];
}else{ //and also here we have no problem
    errorocurred = 1;
}
i was trying to assign to a different spot in the union and also having a union which is not an array works. i can make a workaround of the problem with assigning first to MANDO12345FLG and moving afterwards the complete union via:

Code: Select all

MANDOFLG[i].reg = MANDO12345FLG.reg;

here is the complete section of code but it really is just as i pointed out above that only on this one line it cant resolve

Code: Select all

for(i = 0; i < 5; i++){
        errorocurred = 0;
        FLASH_Read(MEM_page_config_Mando + (i * 128), flashdata, 128);//FLASH_Read(172032 + (i * 256), flashdata, 128); 
        for(j = 0;j < 128; j++){
            fsdata[2 * j] = Lo(flashdata[j]); // & 0x00FF;
            fsdata[2 * j + 1] = Hi(flashdata[j]); // >> 8) & 0x00FF;
        }
        
        if(Dv_mima(fsdata[ADR_virarvalue], cVirarminval, cVirarmaxval) ==  1){
            Mando_var[i].virarvalue = fsdata[ADR_virarvalue];
        }else{
            errorocurred = 1;
        }
        if(Dv_mima(fsdata[ADR_desvirarvalue], cDesvirarminval, cDesvirarmaxval) ==  1){
            Mando_var[i].desvirarvalue = fsdata[ADR_desvirarvalue];
        }else{
            errorocurred = 1;
        }
        if(Dv_mima(fsdata[ADR_largarvalue], cLargarminval, cLargarmaxval) ==  1){
            Mando_var[i].largarvalue = fsdata[ADR_largarvalue];
        }else{
            errorocurred = 1;
        }
        if(Dv_mima(fsdata[ADR_margenvalue], cMargenminval, cMargenmaxval) ==  1){
            Mando_var[i].margenvalue = fsdata[ADR_margenvalue];
        }else{
            errorocurred = 1;
        }
        
        if(Dv_bol(fsdata[ADR_mando_active]) == 1) {
            MANDOFLG[i].isactive = fsdata[ADR_mando_active]; //after this line...
        }else{    // the debugger stucks here 
            errorocurred = 1;
        }

        if(Dv_bol(fsdata[ADR_fullrecorido]) == 1) {
             MANDOFLG[i].fullrange = fsdata[ADR_fullrecorido];
        }else{
            errorocurred = 1;
        }
        if(Dv_bol(fsdata[ADR_direccion]) == 1) {
             MANDOFLG[i].inverted = !fsdata[ADR_direccion];
        }else{
            errorocurred = 1;
        }
        if(Dv_bol(fsdata[ADR_remote]) == 1) {
             MANDOFLG[i].remote = fsdata[ADR_remote];
        }else{
            errorocurred = 1;
        }
        if(errorocurred == 1) {
            MANDOFLG[i].isactive = 0;
            errhandler(cMandoerror, i);
        }
}

but i really would like to understand where the problem is in the above.
has anyone else had a problem like that before?
I am using workstation 7 with a PIC 24EP512GU810

it is not a problem of the debugger because if i program it in release mode i get the same results in the way that the chip does no longer respond if i leave this section but works fine if i comment it out.

Dieter


I reduced the whole thing down and made a complete project if somebody likes to give it a try. There might still some comments floating around in there but well, I am posting it here:

Code: Select all

// my sign ±±±


//#include <p24EP512GU810.h>
//#include "C:\Users\Tecnico\MPLABXProjects\PIC24EP512GU810_Test.X\p24EP512GU810.h"



//****************************PROTOTYPES*********************
void INIT();
void Mandos_init();
void myclrwdt(void);
unsigned char Dv_mima(unsigned int int_data, unsigned int minval, unsigned int maxval);
unsigned char Dv_bol(unsigned char bol_data);

//*******************END OF PROTOTYPE DECLARATIONS***************************

union {

    struct {
        unsigned loopexit : 4; //LSB
        unsigned : 1;
        unsigned state : 3; //test,active, compc
    };

    struct {
        unsigned rs232rx      : 1; //LSB
        unsigned rs232tx      : 1;
        unsigned temporizador : 1; //  The Flag which indicates to send data to PC
        unsigned button       : 1;
        unsigned H_L          : 1; //if ADC_POWER is High or Low set--> Digitalñ setting on chckwakeup
        unsigned Tam1_TMR_on  : 1;
        unsigned Tam2_TMR_on  : 1;
        unsigned Tam3_TMR_on  : 1; //MSB
    };
}   ISRFLG;

 union manflg{

      struct  {
              unsigned reg  : 16;
      };
      struct  {
              unsigned ud1     : 1;
              unsigned macu    : 2; // macu Mando calculo
              unsigned ud2     : 11;
              unsigned tambor  : 2;
      };
      struct  {
              unsigned isactive   : 1;  //LSB
              unsigned fullrange  : 1;// if 1 then 0 - 5V range
              unsigned inverted   : 1; // if 1 then left is full
              unsigned remote     : 1;  // is remote controlled at the moment
              unsigned inparo     : 1;   // if 1 then Mando is in Paro --> relacionado a sus config!!
              unsigned b5         : 1;
              unsigned b6         : 1;  //LSB
              unsigned b7         : 1;
              unsigned b8         : 1;
              unsigned b9         : 1; //if PC_bit == 0 PVG
              unsigned b10        : 1; // if PC_bit == 1 Convertidor
              unsigned b11        : 1;
              unsigned b12        : 1;
              unsigned b13        : 1;
              unsigned tambitL    : 1;
              unsigned tambitH    : 1;
      };
};

union manflg MANDO12345FLG;
union manflg MANDOFLG[5];

unsigned char fsdata[256];
unsigned char i = 0;
 #define       ADR_mando_active       0x03    // el mando no es activable(like not installed) and therefore not visible on startup  0 = not installed
 #define       ADR_remote             0x04    // 0 = no es possible remote, 1 = es posible de remote control
 #define       ADR_direccion          0x05   // 0 es normal, 1 es invertido
 #define       ADR_fullrecorido       0x10 // cuando lanzando el mando es en modo de completo uso para lanzar

// //****************Registerbits- Interrupts************************************
#define               TMR1IF                            IFS0.T1IF
#define               TMR1_on                           T1CONbits.TON
#define               TMR1IE                            IEC0bits.T1IE
#define               GIE                               INTCON2.GIE


#define                TMR1OF_constant                  0x0E0E

#define     ISRtestled        LATFbits.LATF5          //ISR Testled(blinking on ISR TMR 1 OFx5


#include "built_in.h"


void main() {
    INIT();
    while(1){
        if(ISRFLG.button){
            ISRFLG.button = 0;
            Mandos_init();
        }
    }
}


void TMR1isr() iv IVT_ADDR_T1INTERRUPT ics ICS_AUTO {
    static unsigned char TMR1cnt = 0;   //Tmr1 OF every 200ms at the moment
    TMR1IF = 0;
    TMR1cnt++;
    ISRFLG.temporizador = 1;
    if(TMR1cnt == 40){
        TMR1cnt = 0;
        ISRtestled = !ISRtestled;
    }
}

 void IOCisr() iv IVT_ADDR_CNINTERRUPT ics ICS_AUTO {
 IFS1bits.CNIF = 0;
 ISRFLG.button = 1;

}


void INIT(void){

    unsigned int db1 = 0;

    PLLFBD = 38; // M = 65
    CLKDIVbits.PLLPOST = 0; // N1 = 2
    CLKDIVbits.PLLPRE = 0; // N2 = 2
    OSCTUN = 0; //Fin = 7.37MHz
    db1 = OSCCONbits.COSC;

    while (OSCCONbits.LOCK != 1);

    //*************************Analog & TRIS *******************************
    ANSELA = 0x0000;
    ANSELB = 0x023F;     //RB0;RB4;RB5,RB9 analog
    ANSELC = 0x0000;
    ANSELD = 0x0000;
    ANSELE = 0x0100;

    ANSELG = 0x0000;

    //**************and then input output...************************************
    //*********see the Excel for Details***************************

    TRISA = 0x0008;    //Ra3 = button
    TRISB = 0x023F;   //RB0 & RB2 analog--> for the debugging Board and therefore input
    TRISC = 0x0000;
    TRISD = 0x0008;
    TRISE = 0x0100;
    TRISF = 0x0100;
    TRISG = 0x0000;


    LATA = 0x0000;
    LATB = 0x0000;
    LATC = 0x0000;
    LATD = 0x0000;
    LATE = 0x0000;
    LATF = 0x0000;
    LATG = 0x0000;


    CNPDA = 0x0000;
    CNPDB = 0x0000;
    CNPDC = 0x0000;
    CNPDD = 0x0000;
    CNPDE = 0x0000;
    CNPDF = 0x0000;
    CNPDG = 0x0000;

    CNPUA = 0x0000;
    CNPUB = 0x0000;
    CNPUC = 0x0000;
    CNPUD = 0x0000;
    CNPUE = 0x0000;
    CNPUF = 0x0000;
    CNPUG = 0x0000;

 //*******************Interrupt on Change**********************
    // we try first with RA3-----------------
   CNENAbits.CNIEA3 = 1;
   IEC1bits.CNIE = 1;
   IFS1bits.CNIF = 0;


   
//*******************configure the Peripheral Pin Select registers here depending on the need **************************

    Unlock_IOLOCK();

// *******************************PPS_Mapping UART1**********************
 // Rx1 to RD3    that is because WS7 has this distribution
 // Tx1 to RD1
    RPOR0bits.RP65R = 1;      // this command sets RP65--(RD1) to UART1 Tx
    RPINR18bits.U1RXR = 67;
// ****************************** PPS_Mapping SPI1***************************

    Lock_IOLock();


 //******************  TIMER 1  **************************
  
    T1CONbits.TON = 0; // Disable Timer
    T1CONbits.TCS = 0; // Select internal instruction cycle clock
    T1CONbits.TGATE = 0; // Disable Gated Timer mode
    T1CONbits.TCKPS = 3;  //0b011; // Select 1:256 Prescaler
    TMR1 = 0x00; // Clear timer register
    PR1 = TMR1OF_constant; //9; // Load the period value
    IPC0bits.T1IP = 0x01; // Set Timer 1 Interrupt Priority Level
    IFS0bits.T1IF = 0; // Clear Timer 1 Interrupt Flag
    IEC0bits.T1IE = 1; // Enable Timer1 interrupt
    T1CONbits.TON = 1; // Start Timer

}

void Mandos_init(){

 unsigned char i = 0;
 //unsigned char j = 0;
// bit errorocurred;
 unsigned char errorocurred;

    for(i = 0; i < 5; i++){
        fsdata[ADR_mando_active] = 1;
        if(Dv_bol(fsdata[ADR_mando_active]) == 1) {
          MANDO12345FLG.isactive =  fsdata[ADR_mando_active];  //
          MANDOFLG[i].isactive =  MANDO12345FLG.isactive; //
          MANDOFLG[i].isactive =  fsdata[ADR_mando_active];  //asigns wrong values and does not work afterwards correctly
        }else{ // and keeps stucking here
          errorocurred = 1;
        }
    }
}

unsigned char Dv_bol(unsigned char bol_data){
    if(bol_data > 1){
        return 0; //datavalidation failed
    }else{
        return 1;  //datavalidation was good
    }
}

unsigned char Dv_mima(unsigned int int_data, unsigned int minval, unsigned int maxval){
    if((int_data < minval) || (int_data > maxval)){
        return 0;   //datavalidation failed
    }else{
        return 1;   //datavalidation was good
    }
}

 void myclrwdt(void){
  asm{clrwdt}

}
Even reduced down to this it does not work properly and i cant see why not. it would be possible to reduce it further but anyway,

Dieter

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Unable to resolve else statement after assigning to a un

#2 Post by filip » 26 Mar 2019 14:48

Hi,

Please, can you attach the minimal project that represents this issue ?

Regards,
Filip.

EESL
Posts: 12
Joined: 04 Feb 2019 15:30

Re: Unable to resolve else statement after assigning to a un

#3 Post by EESL » 27 Mar 2019 14:10

Hello Filip

I was trying with the code that i am posting here underneath and it is not working. but I can give a little bit more of information because if i comment out the ISR for the TMR 1 it seem to work. So there seems to be a connection but i really do not know. Also if i run the simulator it does work but neither in debugging mode or in release mode it works.

Code: Select all


// my sign ±±±


 union manflg{

      struct  {
              unsigned reg  : 16;
      };
      struct  {
              unsigned ud1     : 1;
              unsigned macu    : 2; // macu Mando calculo
              unsigned ud2     : 11;
              unsigned tambor  : 2;
      };
      struct  {
              unsigned isactive   : 1;  //LSB
              unsigned fullrange  : 1;// if 1 then 0 - 5V range
              unsigned inverted   : 1; // if 1 then left is full
              unsigned remote     : 1;  // is remote controlled at the moment
              unsigned inparo     : 1;   // if 1 then Mando is in Paro --> relacionado a sus config!!
              unsigned b5         : 1;
              unsigned b6         : 1;  //LSB
              unsigned b7         : 1;
              unsigned b8         : 1;
              unsigned b9         : 1; //if PC_bit == 0 PVG
              unsigned b10        : 1; // if PC_bit == 1 Convertidor
              unsigned b11        : 1;
              unsigned b12        : 1;
              unsigned b13        : 1;
              unsigned tambitL    : 1;
              unsigned tambitH    : 1;
      };
};

union manflg MANDO12345FLG;
union manflg MANDOFLG[5];

unsigned char fsdata[256];
unsigned char i = 0;
 #define       ADR_mando_active       0x03    //

// //****************Registerbits- Interrupts************************************
#define               TMR1IF                            IFS0.T1IF
#define               TMR1_on                           T1CONbits.TON
#define               TMR1IE                            IEC0bits.T1IE
#define               GIE                               INTCON2.GIE


#define                TMR1OF_constant                  0x0E0E

#define     ISRtestled        LATFbits.LATF5          //ISR Testled(blinking on ISR TMR 1 OFx5


#include "built_in.h"


void main() {
    //INIT();
        //*************************Analog & TRIS *******************************
    ANSELA = 0x0000;
    ANSELB = 0x023F;     //RB0;RB4;RB5,RB9 analog
    ANSELC = 0x0000;
    ANSELD = 0x0000;
    ANSELE = 0x0100;

    ANSELG = 0x0000;

    //**************and then input output...************************************
    //*********see the Excel for Details***************************

    TRISA = 0x0008;    //Ra3 = button
    TRISB = 0x023F;   //RB0 & RB2 analog--> for the debugging Board and therefore input
    TRISC = 0x0000;
    TRISD = 0x0008;
    TRISE = 0x0100;
    TRISF = 0x0100;
    TRISG = 0x0000;


    LATA = 0x0000;
    LATB = 0x0000;
    LATC = 0x0000;
    LATD = 0x0000;
    LATE = 0x0000;
    LATF = 0x0000;
    LATG = 0x0000;


    CNPDA = 0x0000;
    CNPDB = 0x0000;
    CNPDC = 0x0000;
    CNPDD = 0x0000;
    CNPDE = 0x0000;
    CNPDF = 0x0000;
    CNPDG = 0x0000;

    CNPUA = 0x0000;
    CNPUB = 0x0000;
    CNPUC = 0x0000;
    CNPUD = 0x0000;
    CNPUE = 0x0000;
    CNPUF = 0x0000;
    CNPUG = 0x0000;




 //******************  TIMER 1  **************************

    T1CONbits.TON = 0; // Disable Timer
    T1CONbits.TCS = 0; // Select internal instruction cycle clock
    T1CONbits.TGATE = 0; // Disable Gated Timer mode
    T1CONbits.TCKPS = 3;  //0b011; // Select 1:256 Prescaler
    TMR1 = 0x00; // Clear timer register
    PR1 = TMR1OF_constant; //9; // Load the period value
    IPC0bits.T1IP = 0x01; // Set Timer 1 Interrupt Priority Level
    IFS0bits.T1IF = 0; // Clear Timer 1 Interrupt Flag
    IEC0bits.T1IE = 1; // Enable Timer1 interrupt
    T1CONbits.TON = 1; // Start Timer
    
    
    while(1){
        for(i = 0; i < 5; i++){
           fsdata[ADR_mando_active] = 1;
           MANDO12345FLG.isactive =  fsdata[ADR_mando_active];  // This works
           MANDOFLG[i].isactive =  MANDO12345FLG.isactive; // and also this works
           MANDOFLG[i].isactive =  fsdata[ADR_mando_active];  //asigns wrong values sometimes and FAILS after here
           asm{clrwdt}
        }
    }
}


void TMR1isr() iv IVT_ADDR_T1INTERRUPT ics ICS_AUTO {
    static unsigned char TMR1cnt = 0;   //Tmr1 OF every 200ms at the moment
    TMR1IF = 0;
    TMR1cnt++;
    if(TMR1cnt == 40){
        TMR1cnt = 0;
        ISRtestled = !ISRtestled;
    }
}


If you would prefer i can email the .c file if you want but it seems that it is not possible to upload c or h files here in the forum.
Anyway, i hope you can tell me something about this issue at some point.

Dieter
Attachments
Union_error.rar
(1.41 KiB) Downloaded 98 times

Post Reply

Return to “mikroBasic PRO for dsPIC30/33 and PIC24 General”