CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Menu structure

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PrinceNai



Joined: 31 Oct 2016
Posts: 479
Location: Montenegro

View user's profile Send private message

Menu structure
PostPosted: Wed Jan 19, 2022 8:25 am     Reply with quote

Hi,

a while ago (29.6.2019) I posted a code with a menu structure which worked OK and happily compiled under version 5.078. An user sent me a PM few days ago, saying the code doesn't compile under version 5.104 or 5.105. I tested it and he was right, it doesn't. It reports an error "function expected" on the line marked in the code below. Any ideas?

Code:

typedef void(*_fptr)(void);      // added by PCM Programmer
                                                 
typedef rom struct MenuStructure{
   rom char  *text;
   unsigned char num_menupoints;
   unsigned char up;
   unsigned char down;
   unsigned char enter;
//   void (*fp)(void);           // original, not working
   _fptr fp;                      // added by PCM Programmer
   }             
   MenuEntry;   


The error is reported where marked:


Code:



void browse_menu (void){
   do{
      Exit = 0;
      show_menu();                                                 
     
// de-bounce is done in interrupt routine
      if(UP_switch_is_down == 1){
         UP_switch_is_down = 0;
         selected = Menu[selected].up;
      }
      if(DOWN_switch_is_down == 1){
         DOWN_switch_is_down = 0;       
         selected = Menu[selected].down;
      }
      if(ENTER_switch_is_down == 1){
         ENTER_switch_is_down = 0;
         if(Menu[selected].fp != 0){
//            Menu[selected].fp();              // original, not working

//*******************************************************
            *Menu[selected].fp();               // added by PCM Programmer, V. 5.104 chokes here, saying expecting function
//******************************************************
         }
         if(!Exit){
            selected = Menu[selected].enter;
         }
         else{
            selected = 1;                       // make sure the entry point to the menu is always 1
         }
      }                                       
   }                                                           
   while(!Exit);                                // you need some kind of stop condition to exit menus
                                                         
}  // function

Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Wed Jan 19, 2022 9:04 am     Reply with quote

it originally going wrong, would have been with 5.080. There was a change at
this point which caused pointer handling issues. The thread about this in
in the 'issues' forum. Now the latest compilers have fixed this one, question
is whether it has fixed your problem as well.
Can you post a mini compilable program, that would allow us to test?.
PrinceNai



Joined: 31 Oct 2016
Posts: 479
Location: Montenegro

View user's profile Send private message

PostPosted: Wed Jan 19, 2022 9:56 am     Reply with quote

It is all inter-connected, so I really can't or don't know how to) make it much shorter :-). So here is a copy of a project that does compile under 5.078. The point where it fails is the function "void browse_menu (void)" in menu_structure.c

menu.h
Code:

#include <18F4550.h>
#device ADC=10
//#device PASS_STRINGS = IN_RAM    //copy all the strings to RAM to allow access with pointer
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES DEBUG
 
#device ICD=TRUE
#use delay(internal, clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=RS232,errors)
#use i2c(Master,Slow,sda=PIN_B0,scl=PIN_B1, force_hw)


menu.c

Code:

#include    <menu.h>
#include    <string.h>
#include    <i2c_Flex_LCD_driver.c>       //LCD driver 


#define  UP_switch   PIN_A3
#define  DOWN_switch   PIN_A2
#define  ENTER_switch   PIN_A1
int8 UP_switch_is_down = FALSE;           // button flags                   
int8 DOWN_switch_is_down = FALSE;                     
int8 ENTER_switch_is_down = FALSE;

#include    <menu_structure.h>
#include    <menu_structure.c>                                           
                             
unsigned int8 COUNTER = 0;

int8 GO = 0;                              // GO flag, indikates start of main loop
int8 Tmp = 0;
int8 Heartbeat = 0; 

#define FOSC getenv("CLOCK")              // Get PIC oscillator frequency
// check if it is below or equal to 20MHz                 
#if(FOSC < 21000000)
  #define TIMER0_PRELOAD (256 - (FOSC/4/256/100))
#else
  #error Oscillator frequency is too high:  FOSC
#endif                                           

                                   
#define  LED1      PIN_D3           
#define  LED2      PIN_D4
#define  LED3      PIN_D5

                               
int8 Cntr = 0;                             

// ****************************************************************************
// function declarations
// ****************************************************************************
void timer0_init(void);

                                               
                           

// ****************************************************************************
#INT_TIMER0
void timer0_isr(void){     
   Cntr++;
   if(Cntr == 5){                                           // toggle led every 100ms
      output_toggle(LED1);
      Cntr = 0;   
   }
// debounce   
   int8 active_state_UP, previuos_state_UP,                       
        active_state_DOWN, previuos_state_DOWN,
        active_state_ENTER, previuos_state_ENTER;
   
   set_rtcc(TIMER0_PRELOAD);                                // Reload Timer0 for 10ms rate
   
   active_state_UP = input(UP_switch);                      // Read the button
   active_state_DOWN = input(DOWN_switch);                  // Read the button
   active_state_ENTER= input(ENTER_switch);                 // Read the button
   
   if((previuos_state_UP == 1) && (active_state_UP == 0)){
      UP_switch_is_down = TRUE;                             // raise "BUTTON PRESED" flag. Must be cleared in software.
//      output_toggle(LED1);
   }

   if((previuos_state_DOWN == 1) && (active_state_DOWN == 0)){                       
      DOWN_switch_is_down = TRUE;                           // raise "BUTTON PRESED" flag                         
//      output_toggle(LED2);
   }                                                 

   if((previuos_state_ENTER == 1) && (active_state_ENTER == 0)){                       
      ENTER_switch_is_down = TRUE;                          // raise "BUTTON PRESED" flag
//      output_toggle(LED3);             
   }                                             
                                 
   previuos_state_UP = active_state_UP;                     // Save current value for next time
   previuos_state_DOWN = active_state_DOWN;                 // Save current value for next time
   previuos_state_ENTER = active_state_ENTER;               // Save current value for next time
}                                               
                     
// ****************************************************************************                                                                                                                                                     
#INT_TIMER1                                  // cca. 131ms overflow
void  TIMER1_isr(void) {                             
   COUNTER++;
   if(COUNTER == 16){                 
      COUNTER = 0;                     
      GO = 1;               
      Heartbeat++;                           // display a changing symbol on the  LCD to see it is working
   }                                     
}
// ****************************************************************************
                                                                                   
                                   
// ****************************************************************************
                                                                                                                 
void main() {
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);      //131 ms overflow
   enable_interrupts(INT_TIMER1);
   timer0_init();
   enable_interrupts(GLOBAL);
   port_b_pullups(true);
   lcd_init();                                  // init LCD   
   Delay_ms(100);               
   lcd_putc('\f');                     

   while(TRUE){
                                   
      lcd_gotoxy(1,1);
      lcd_putc("Press ENTER for menu");
     
      if(ENTER_switch_is_down){
         ENTER_switch_is_down = 0;
         browse_menu ();             
      }                                             
      delay_ms(100);                       
   }        // while true
                                                 
}           // main 

// ****************************************************************************
// FUNCTIONS
// ****************************************************************************

void timer0_init(void)
{
   setup_timer_0(T0_INTERNAL | T0_DIV_256 | T0_8_BIT);
   set_timer0(TIMER0_PRELOAD);
   clear_interrupt(INT_TIMER0);
   enable_interrupts(INT_TIMER0);
}


menu_structure.c

Code:

//#define FLOATING_HEADER 0                  // menu header disapears with browsing
#define FLOATING_HEADER 1                    // menu header always stays on top
void strromcpy(char *dest, rom char *source);                                                   
void LcdWriteStringRom (int8 x, int8 y, rom int8 *LCD_Data, int8 clear_line);       
void show_menu (void);
void browse_menu (void);
void start(void);
void dummy(void);                                               
void ClearMinus (void);
void Blank (void);
void ExitMenu(void);
void DisplaySelectedOption(void);
// functions for menus and sub-menus. Note they all start with 1 and the function for last one is always return up, so it is not needed
void Main1(void);
void Main2(void);
void Main3(void);                                     
//
void Sub101(void);
void Sub102(void);         
//
void Sub201(void);                         
void Sub202(void);
void Sub203(void);
void Sub204(void);
void Sub205(void);
void Sub206(void);
//
void Sub301(void);                         
void Sub302(void);
void Sub303(void);
void Sub304(void);
void Sub305(void);
void Sub306(void);
//

int8 ROM_String_Length = 0;                                                                                                                     
char ROM_String_Copy[21]; 
#define ROW_LENGTH 20                     // uncoment for your display size, TBD for displays other than 4x20
//#define ROW_LENGTH 16                           

int8 line_cnt_g = 1;                      // first line on LCD is 1, different than tutorial
int8 from_g = 0;                          // declare global copies of variables from show_menu to be able to see tham all the time with debugger                               
int8 till_g = 0;                                                   
int8 temp_g = 0;                          // calculate the span of addresses for the current menu             
int8 Intermediate_g = 0;                                                                                 
int8 Position = 0;
int8 Exit = 0;
int8 FloatingHeaderAddress = 0;           // this is the address of the first entry of the current menu, i.e. header
                                          // that can be used for a "non disappearing header" style of the menu                                           
                                                                                                                                                               
// menu options texts                           
rom char menu_000[] = " [MAIN MENU -0]";     // 0
rom char menu_001[] = " main_001-1";         // 1
rom char menu_002[] = " main_002-2";         // 2
rom char menu_003[] = " main_003-3";         // 3
rom char menu_004[] = " EXIT MENU-4";        // 4
// sub-menu 1 text                               
rom char menu_100[] = " [SUB-MENU1 -5]";     // 5
rom char menu_101[] = " sub_101-6";          // 6
rom char menu_102[] = " sub_102-7";          // 7
rom char menu_103[] = " SUB-MENU1 EXIT -8";  // 8
// sub-menu 2 text                               
rom char menu_200[] = " [SUB-MENU2 -9]";     // 9
rom char menu_201[] = " sub_201-10";         // 10
rom char menu_202[] = " sub_202-11";         // 11
rom char menu_203[] = " sub_203-12";         // 12
rom char menu_204[] = " sub_204-13";         // 13
rom char menu_205[] = " sub_205-14";         // 14
rom char menu_206[] = " sub_206-15";         // 15
rom char menu_207[] = " SUB-MENU2 EXIT";     // 16
 // sub-menu 3 text                               
rom char menu_300[] = " [SUB-MENU3 -17]";    // 17
rom char menu_301[] = " sub_301-18";         // 18
rom char menu_302[] = " sub_302-19";         // 19
rom char menu_303[] = " sub_303-20";         // 20
rom char menu_304[] = " sub_304-21";         // 21
rom char menu_305[] = " sub_305-22";         // 22
rom char menu_306[] = " sub_306-23";         // 23
rom char menu_307[] = " SUB-MENU3 EXIT";     // 24
                         

// ******************** END MENU TEXT *****************************************
                                                                                                                                                                           
static unsigned int8 selected = 1;           // indicates selected menu item. Start with 1, because we don't want to pick the header
                                                                                                                     
// every element of the array must have all elements defined in the prototype: text, number of elements, up, down, enter and function (can be null)

// This array is the actual structure of the menu. It tells what the keys are doing,
// what the text to be displayed is and what function to execute if you hit ENTER key.
// So: text, number of options in this section, up key transition, down key, enter key and optional function
// when you press enter

MenuEntry Menu[] = {                         // at least one function must be defined, else it doesn't compile
//   text, size, u, d, e, function
   {menu_000, 5, 0, 0, 0, 0},                //0; option 0; text 0; 5 options, up button menu_000, down button menu_000, enter menu_000, no function attached - non browsable
   {menu_001, 5, 4, 2, 6, 0},           
//   {menu_001, 5, 1, 2, 6, 0},                //1; text 1; 5 options, up button stays in menu_001, down button goes to menu_002, enter goes to sub-menu_101, no function attached
   {menu_002, 5, 1, 3, 10, 0},               //2; text 2; 5 options, up button goes to menu_001, down button goes to menu_003, enter sub-menu_201, no function attached
   {menu_003, 5, 2, 4, 18, 0},               //3; text 3; 5 options, up button goes to menu_002, down button goes to menu_004, enter stays in menu_003, no function attached
//   {menu_004, 5, 3, 4, 4, ExitMenu},         //4; text 4; 5 options, up button goes to menu_003, down button stays in menu_004 {no roll-over}, enter stays in menu_004 and executes ExitMenu function
   {menu_004, 5, 3, 1, 4, ExitMenu},         //4; down key points back to the top, option 1
                                                                                                                                                                                                                                                                   
// sub-menu for menu_001
   {menu_100, 4, 0, 0, 0, 0},                //5; option 5; text 5; 4 options,sub-menu 1 header, non browsable 
//   {menu_101, 4, 6, 7, 6, dummy},            //6; text 6; 4 options, up button stay in menu_101, down button menu_102, enter menu_101, execute dummy function
   {menu_101, 4, 8, 7, 6, dummy},            // up button goes back to the bottom
   {menu_102, 4, 6, 8, 7, Sub102},           //7; text 7; 4 options, up button menu_101, down button menu_103, enter menu_102, function Sub102
//   {menu_103, 4, 7, 8, 1, Blank},            //8; down key stays on the last option
   {menu_103, 4, 7, 6, 1, Blank},            // 8;down key moves back to the top, option 6
                                                                                                                                   
// sub-menu for menu_002
   {menu_200, 8, 0, 0, 0, 0},                //9; text 9;  sub-menu 2 header, non-browsable
   {menu_201, 8, 16, 11, 10, Sub201},        // up button goes back to the bottom
//   {menu_201, 8, 10, 11, 10, Sub201},        //10; text 10; sub-menu 2, 8 options, up button menu_201, down button menu_202, enter menu_201, Sub201
   {menu_202, 8, 10, 12, 11, Sub202},        //11; text 11; sub-menu 2, 8 options, up button menu_201, down button menu_203, enter menu_202, Sub202
   {menu_203, 8, 11, 13, 12, Sub203},        //12; text 12; sub-menu 2, 8 options, up button menu_202, down button menu_204, enter menu_203, Sub203
   {menu_204, 8, 12, 14, 13, Sub204},        //13; text 13; sub-menu 2, 8 options, up button menu_203, down button menu_205, enter menu_204, Sub204
   {menu_205, 8, 13, 15, 14, Sub205},        //14; text 14; sub-menu 2, 8 options, up button menu_204, down button menu_206, enter menu_205, Sub205
   {menu_206, 8, 14, 16, 15, Sub206},        //15; text 15; sub-menu 2, 8 options, up button menu_205, down button menu_207, enter menu_206, Sub206
//   {menu_207, 8, 15, 16, 2, 0},              //16; text 16; sub-menu 2, 8 options, up button menu_206, down button menu_207, enter menu_002, no function attached
   {menu_207, 8, 15, 10, 2, 0},              //16; down key points back to the top, option 10
   

// sub-menu for menu_003                                                                     
   {menu_300, 8, 0, 0, 0, 0},                //17; text 17; sub-menu 3 header, non-browsable
   {menu_301, 8, 24, 19, 18, Sub301},        // 18; up button goes back to the bottom
//   {menu_301, 8, 18, 19, 18, Sub301},        //18; text 18; sub-menu 3, 8 options, up button menu_301, down button menu_302, enter menu_301, Sub301
   {menu_302, 8, 18, 20, 19, Sub302},        //19; text 19; sub-menu 3, 8 options, up button menu_301, down button menu_303, enter menu_302, Sub302
   {menu_303, 8, 19, 21, 20, Sub303},        //20; text 20; sub-menu 3, 8 options, up button menu_302, down button menu_304, enter menu_303, Sub303
   {menu_304, 8, 20, 22, 21, Sub304},        //21; text 21; sub-menu 3, 8 options, up button menu_303, down button menu_305, enter menu_304, Sub304
   {menu_305, 8, 21, 23, 22, Sub305},        //22; text 22; sub-menu 3, 8 options, up button menu_304, down button menu_306, enter menu_305, Sub305
   {menu_306, 8, 22, 24, 23, Sub306},        //23; text 23; sub-menu 3, 8 options, up button menu_305, down button menu_307, enter menu_306, Sub306
//   {menu_307, 8, 23, 24, 3, 0}               //24; text 24; down key stays in option 24
   {menu_307, 8, 23, 18, 3, 0}               //24; down key points back to the top, option 18                                                               
                                                                                                 
};                                         
// ********************* END MENU  DEFINITIONS ********************************
                                                                                       
// ****************************************************************************
// functions
// ******************* COPY STRING FROM ROM TO RAM ****************************
void strromcpy(char *dest, rom char *source)                     
{
   while (*source != '\0')                             
       *(dest++) = *(source++);                                   
   *dest='\0';
}                                                                   

// ****************** WRITE A STRING ON LCD FROM ROM **************************
void LcdWriteStringRom (int8 x, int8 y, rom int8 *LCD_Data, int8 clear_line){
   int i = 0;
   lcd_gotoxy(x,y);
   strromcpy(ROM_String_Copy, LCD_Data);                 // copy string from ROM to RAM
   printf(lcd_putc, "%s", ROM_String_Copy);              // display on LCD (assumes 20 characters)
   if(clear_line){                                                                                   
      ROM_String_Length = strlen(ROM_String_Copy) + x;   // get the length of the string, add the offset at the beginning. Otherwise you go over the length of a row
      ROM_String_Length = ROW_LENGTH - ROM_String_Length;// calculate how many are missing till the end of the row of 20 characters
      while(i <=  ROM_String_Length){                    // if clear line is 1, fill the line with blanks
         lcd_putc(" ");
         i++;                                         
      }                                                 
   }                                                                     
}                                                             
// ******************** SHOW THE MENU ON THE LCD ******************************
/*  This function formats the menu. It uses fixed third row for the selected option.
Because of this we split the formating in three parts:
-top of the menu - selected item can be also on first or second row TOP + 2 spaces
-middle of the menu - selected item is in the third row
-bottom of the menu - selected item can sink to the fourth row
*/                                                   
void show_menu (void){
   if(selected > 13){
    delay_cycles(1);   
   }                                             
   int8 line_cnt = 1;                                    // first line on LCD is 1, different than tutorial made with hi-tech that uses 0,0
   int8 from = 0;                                                         
   int8 till = 0;                                                                                   
   int8 temp = 0;                                       
   int8 Intermediate = 0;
// here we use num_menupoints defined in our struct to calculate how many options
// are available in the current menu and with that where in the menu we are with
// the selected option: top, middle or bottom
   while(till <= selected){
      till = till + Menu[till].num_menupoints;
//      till += Menu[till].num_menupoints;           // calculate end position of the current menu
   }                                 
   from = till - Menu[selected].num_menupoints;
   till--;                                               // subtract 1 because numbering starts with 0
   till_g = till;
   temp = from;
   temp_g = temp;
   from_g = from;
   FloatingHeaderAddress = from;                         // this is the address of the first entry of the current menu, i.e. header
                                                         // that can be used for a "non disappearing header" style of the menu

                                                                                                                 
                                                                                                                 
// we are in the middle of menu
  if ((selected >= (from + 2)) && (selected <=  ( till - 1))){          // my selection >= top+2 and < till - 1               
      from = selected - 2 ;                                                                           
      till = from + 3;
      till_g = till;
      from = from + FLOATING_HEADER;
      from_g = from;
      Position = 2;
// floating menu style
      if(FLOATING_HEADER){
         LcdWriteStringRom (2, line_cnt, Menu[FloatingHeaderAddress].text, 1);     // write first row, header
         line_cnt++;   
         line_cnt_g = line_cnt;     
      }
     
      for(from; from <= till; from ++){
         LcdWriteStringRom (2, line_cnt, Menu[from].text, 1);     // first column is just for indicator!!!
         line_cnt++;   
         line_cnt_g = line_cnt;
      }                   
                                                         
      ClearMinus ();       
      lcd_gotoxy(1,3);                                           // mark selected menu item
      lcd_putc ("-");       
                                                                                                             
  }    // if brace
                                                           
// we are within top + 2 spaces
   else                                                                 
   {                                       
     if(selected < (from + 2)){
         Position = 1;

        till = from + 3;
        till_g = till;
        from = from + FLOATING_HEADER;
         from_g = from;
// floating menu style       
         if(FLOATING_HEADER){
            LcdWriteStringRom (2, line_cnt, Menu[FloatingHeaderAddress].text, 1);     // write first row, header
            line_cnt++;   
            line_cnt_g = line_cnt;     
         }       
       
       
       
         for(from; from <= till; from ++){
            LcdWriteStringRom (2, line_cnt, Menu[from].text, 1); // first column is just for indicator!!!
            line_cnt++;
         }
         ClearMinus();           
         Intermediate = (selected - temp + 1);                 // not really needed, can be direct in lcd function
         Intermediate_g = Intermediate;
         
         lcd_gotoxy(1, Intermediate);                          // mark selected menu item
         lcd_putc ("-");                           
                                           
      }   // if                     
// bottom of the menu                   
      if(selected == till){                                    // if the last item on the menu is selected it will be on the fourth row
         from = till - 3 + FLOATING_HEADER;                    // and on LCD we need last string and another three above it
         from_g = from;
         Position = 3;                                                                                                               
// floating menu style         
         if(FLOATING_HEADER){
            LcdWriteStringRom (2, line_cnt, Menu[FloatingHeaderAddress].text, 1);     // write first row, header
            line_cnt++;   
            line_cnt_g = line_cnt;     
         }         
         
         for(from; from <= till; from ++)
         {   LcdWriteStringRom (2, line_cnt, Menu[from].text, 1); // first column stays empty for indicator
            line_cnt++;
         }
         ClearMinus ();
         lcd_gotoxy(1,4);             
         lcd_putc("-");         
     
      }  // if
                           
   }     // else
     
}        // function
// ****************************************************************************

void browse_menu (void){
   do{
      Exit = 0;
      show_menu();                                                 
     
// debounce is done in interrupt routine
      if(UP_switch_is_down == 1){
         UP_switch_is_down = 0;
         selected = Menu[selected].up;
      }
      if(DOWN_switch_is_down == 1){
         DOWN_switch_is_down = 0;       
         selected = Menu[selected].down;
      }
      if(ENTER_switch_is_down == 1){
         ENTER_switch_is_down = 0;
         if(Menu[selected].fp != 0){
//            Menu[selected].fp();              // original, not working
            *Menu[selected].fp();               // added by PCM Programmer
         }
         if(!Exit){
            selected = Menu[selected].enter;
         }
         else{
            selected = 1;                       // make sure the entry point to the menu is always 1
         }
      }                                       
   }                                                           
   while(!Exit);                                // you need some kind of stop condition to exit menus
                                                         
}  // function

// ****************************************************************************
                                                                     
void start(void){                   
}
// ****************************************************************************
void dummy(void)                                             
{                               
   lcd_putc('\f');
//   printf("Hello World\n\r");
   lcd_putc("Working, press ENTER");               
   while(!ENTER_switch_is_down);                // stay here until enter key is hit
   ENTER_switch_is_down = 0;
   lcd_putc('\f');
}                                                         
// ****************************************************************************             
void ClearMinus (void){             
   int8 i = 1;
   for (i = 1; i < 5; i++){
    lcd_gotoxy(1,i);                            // mark selected menu item
    lcd_putc (" ");   
   }                                         
}                                         
// ****************************************************************************
void Blank (void){
   return;
}
// ****************************************************************************
void ExitMenu(void){
   lcd_putc('\f');
   Exit = 1;                                    // signal to exit menu
}

// functions for menus and sub-menus. Note they all start with 1 and the function for last one is always return up, so it is not needed
void Main1(void){
   lcd_putc('\f');                 
   printf("Working, press ENTER");               
   while(!ENTER_switch_is_down);                // stay here until enter key is hit
   ENTER_switch_is_down = 0;
   lcd_putc('\f');
}
void Main2(void){
   lcd_putc('\f');               
   lcd_putc("Working, press ENTER");               
   while(!ENTER_switch_is_down);                // stay here until enter key is hit
   ENTER_switch_is_down = 0;
   lcd_putc('\f');
}
void Main3(void){
   lcd_putc('\f');
   lcd_putc("Working, press ENTER");               
   while(!ENTER_switch_is_down);                // stay here until enter key is hit
   ENTER_switch_is_down = 0;
   lcd_putc('\f');
}
//
void Sub101(void){
   lcd_putc('\f');
   lcd_putc("Working, press ENTER");               
   while(!ENTER_switch_is_down);                // stay here until enter key is hit
   ENTER_switch_is_down = 0;
   lcd_putc('\f');         
}
void Sub102(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
//
void Sub201(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
void Sub202(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
void Sub203(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
void Sub204(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
void Sub205(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
void Sub206(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
//
void Sub301(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
void Sub302(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
void Sub303(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
void Sub304(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
void Sub305(void){
   DisplaySelectedOption();                     // display which menu option was selected
}
void Sub306(void){
   DisplaySelectedOption();                     // display which menu option was selected
}



void DisplaySelectedOption(void){
   lcd_putc('\f');
   printf(lcd_putc, "Selected menu = %u", selected);               
   while(!ENTER_switch_is_down);                // stay here until enter key is hit
   ENTER_switch_is_down = 0;
   lcd_putc('\f');
}                                   



and menu_structure.h

Code:


typedef void(*_fptr)(void);      // added by PCM Programmer
                                                 
typedef rom struct MenuStructure{
   rom char  *text;
   unsigned char num_menupoints;
   unsigned char up;
   unsigned char down;
   unsigned char enter;
//   void (*fp)(void);           // original, not working
   _fptr fp;                      // added by PCM Programmer
   }             
   MenuEntry;                                                             

jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Wed Jan 19, 2022 11:10 am     Reply with quote

There are a couple of confirmed parsing bugs in v5.105, one of which definitely involves function pointers and the other may or may not. I've got two tickets in with CCS. They sent me a fixed DLL for one of them and the other is an intentional bug (still a bug because it causes valid C to generate a compiler error).

In my case, everything worked until at least v5.093, then we upgraded to 5.105 and got all kind of issues ranging from mispaired #if/#endif (which we verified wasn't the case and they gave us a patched DLL to fix) and incorrect compiler errors concerning infinite recursion (again verified this wasn't the case and CCS said it has to do with their changed implementation of function pointers and they aren't sure yet what way they will move forward).

It might be worthwhile sending them your code with the issue via email and seeing if one of the parsing bugs is causing this for you. I had to followup with a phone call after submitting the email, so if you don't see an email response in like 48 hours, I would give them a call to be sure.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Wed Jan 19, 2022 11:56 am     Reply with quote

if I change the code to:
Code:

typedef void(*_fptr)(void);      // added by PCM Programmer

struct MenuStructure{
   rom char  *text;
   unsigned char num_menupoints;
   unsigned char up;
   unsigned char down;
   unsigned char enter;
//   void (*fp)(void);           // original, not working
   _fptr fp;                      // added by PCM Programmer
   } ;           
                                                 
typedef rom struct MenuStructure MenuEntry;   

It does compile. Quite a few 'code has no effect' warnings.

Declaring a named structure inside a typedef, does sound likely to cause
issues.... Especially with it being a rom declaration. With this change it
compiles in 5.105, and 107.
PrinceNai



Joined: 31 Oct 2016
Posts: 479
Location: Montenegro

View user's profile Send private message

PostPosted: Wed Jan 19, 2022 12:28 pm     Reply with quote

Ttelmah,

with 5.104 it doesn't, the same error, Expecting function name. I mean, I can always do it with 5.078 but I hate for a code I posted not to work.

Regarding those warnings I have no idea if it's only compiler's opinion or if the code really just wastes space doing nothing :-). Will test it in the next few days.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Thu Jan 20, 2022 2:30 am     Reply with quote

Jeremiah,
I've had 'intermittent' unbalance #ifdef complaints for quite a few versions.
Will work one day, and then fail on the identical code another day.
Quite annoying.
Does suggest they have changed something in the actual design of the parser,
and perhaps a buffer is overflowing when the code gets to a certain size.
Have you got 5.107?. Does it fix this?. Only been trying it for a few hours
so far, and it has fixed one of my old problems, but not a couple of others.
Haven't had a unbalance #ifdef complaint 'yet'.....
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Fri Jan 21, 2022 6:05 pm     Reply with quote

I haven't gotten 5.107 yet. Our IT policies make it a pain to approve full installations, so we don't do it as often. When I put in the ticket they sent me a fixed DLL for v5.105 (which IT was quickly able to just file copy over) That fixed the #if/#endif "sort of". I still get the errors occasionally, but a recompile removes them.

It didn't fix my "infinite recursion" error in other projects. A later response from support indicated that the compiler was confusing multiple function pointers that had the same basic signature and so it thought there was recursion when there wasn't. They said that was due to a newer way they handle function pointers. They were in discussion on how to handle that though as it was an intentional design decision for the compiler.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sun Jan 23, 2022 3:58 am     Reply with quote

On the warnings about 'code has no effect', it is right.

You have:
Code:

      for(from; from <= till; from ++){


If you want 'from' to be unchanged, the correct syntax is:
Code:

      for(; from <= till; from ++){


It does do absolutely nothing!...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group