Codewarrior 6.0 for Microcontrollers & 9S08AW60

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Codewarrior 6.0 for Microcontrollers & 9S08AW60

Jump to solution
3,598 Views
v_dave
Contributor IV
Hello All,
 
For those that have seen my previous posts you know I have been working with a third party GUI library for graphic LCDs.  Part of the idea behind these GUI libs is compatibility with any compiler so there is not any processor specific calls made in the lib itself.  I have to provide all the low level (the actual writes\reads from the MCU to the LCD controller) which is no problem since the LCD Controller is setup for SPI.
 
Anyways I keep sending random 0x00 command or data bytes to the LCD controller out the SPI port and I couldn't figure out why.  Well I think I hve narrowed down the problem but I am not sure if it's a bug in the compiler or with the GUI libs.
 
Here is a snippet of the code along with the ASM info from the listing file:
Code:
// This is important since it redifines the function sgwrby()#define  sgwrby(a,d) simwrby((a),(d))#define  sgrdby(a)   simrdby((a))// Here is my function that inits the LCD by using the ghw_cmd() function109:  void Display_init(void)   //UC1601  AVC1  110:  {                                       Function: Display_initSource  : C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\CODE\UA_Disp_A.cOptions : -Cs08 -D__NO_FLOAT__ -Env"GENPATH=C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\bin;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\prm;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\Sources;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\src;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\lib;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\src;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\cmd;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\CODE;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\DOC;C:\Projects\Universal Actuator\Software\UA_Disp_A;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\asm_include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\HC08c\include" -Env"LIBPATH=C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\asm_include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\HC08c\include" -Env"OBJPATH=C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\bin" -Env"TEXTPATH=C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\bin" -Lasm=%n.lst -Ll=logfile.txt -Ms -ObjN="C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\UA_Disp_A_Data\Standard\ObjectCode\UA_Disp_A.c.o" -OiLib -WmsgSd1106  111:      ghw_cmd(0xe2);          //SET RESET  0000 aee2     [2]             LDX   #-30   // this is loading 0xe2 into the X register  0002 ad45     [5]             BSR   L49 ;abs = 0049// This is the actual function// SGUCHAR = unsigned char 8-bits of course 247:  void ghw_cmd( SGUCHAR cmd )  248:     {Function: ghw_cmdSource  : C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\CODE\ghwinit.cOptions : -Cs08 -D__NO_FLOAT__ -Env"GENPATH=C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\bin;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\prm;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\Sources;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\src;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\lib;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\src;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\cmd;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\CODE;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\DOC;C:\Projects\Universal Actuator\Software\UA_Disp_A;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\asm_include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\HC08c\include" -Env"LIBPATH=C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\asm_include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\HC08c\include" -Env"OBJPATH=C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\bin" -Env"TEXTPATH=C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\bin" -Lasm=%n.lst -Ll=logfile.txt -Ms -ObjN="C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\UA_Disp_A_Data\Standard\ObjectCode\ghwinit.c.o" -OiLib  249:     #ifdef GHW_PCSIM  250:     ghw_cmd_KS07XXsim( cmd );  251:     #endif  252:    253:     #ifndef GHW_NOHDW  254:     ghw_wait();  255:     sgwrby(GHWCMD, cmd);  0000 5f       [1]             CLRX  // remember we loaded the variable we were passing                                      // now we just cleared X register so we lost the data                                       // we are trying to send  0001 cc0000   [4]             JMP   simwrby  // this is calling the redefined sgwrby()  256:     #endif  257:     }// here is the simwrby()    56:  void simwrby(SGUCHAR adr, SGUCHAR dat)   57:     {Function: simwrbySource  : C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\CODE\bussim.cOptions : -Cs08 -D__NO_FLOAT__ -Env"GENPATH=C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\bin;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\prm;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\Sources;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\src;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\lib;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\src;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\cmd;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\CODE;C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\DOC;C:\Projects\Universal Actuator\Software\UA_Disp_A;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\asm_include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\HC08c\include" -Env"LIBPATH=C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\hc08c\device\asm_include;C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.0\lib\HC08c\include" -Env"OBJPATH=C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\bin" -Env"TEXTPATH=C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\bin" -Lasm=%n.lst -Ll=logfile.txt -Ms -ObjN="C:\Projects\Universal Actuator\Software\UA_Disp_A\UA_Disp_A\UA_Disp_A_Data\Standard\ObjectCode\bussim.c.o" -OiLib -WmsgSd1106  0000 89       [2]             PSHX     58:     register SGUCHAR tmp,msk;   59:     /* 1. Read state of unused bits and initiate used bits for chipselect */   60:    // tmp = (sgrdby(_PTFD) & (~(A0|SCLK|SDA|CS))) | ((adr & 0x1) — A0 : 0);   61:     62:     /* 2. Set chip select (and clock) low, update address bit */   63:    // sgwrby(_PTFD, tmp);   64:     65:     /* 3. Loop while clocking data out, msb first */   66:  //   msk=0x80;   67:  //   do   68:  //      {   69:  //      if (((dat & msk) != 0))   70:  //         {   71:           //sgwrby(_PTFD,tmp|SDA);           /* 4.a Set data high  (other bits is unchanged) */   72:           //sgwrby(_PTFD,tmp|SDA|SCLK);      /* 5.a Set clock high (other bits is unchanged) */   73:           //sgwrby(_PTFD,tmp|SDA);           /* 6.a Set clock low  (other bits is unchanged) */   74:  //         }   75:  //      else   76:  //         {   77:           //sgwrby(_PTFD,tmp);               /* 4.b Set data low   (other bits is unchanged)*/   78:          // sgwrby(_PTFD,tmp|SCLK);          /* 5.b Set clock high (other bits is unchanged)*/   79:          // sgwrby(_PTFD,tmp);               /* 6.b Set clock low  (other bits is unchanged)*/   80:  //         }   81:  //      msk >>= 1;   82:  //      }   83:  //   while(msk != 0);   84:     85:     /* 7. Set chip select high (SCLK must remain low here) */   86:     //sgwrby(_PTFD,tmp|CS);   87:     88:          if(!adr)  0001 95       [2]             TSX     0002 7d       [3]             TST   ,X  0003 2602     [3]             BNE   L7 ;abs = 0007   89:              LCD_CD_ClrVal();  0005 1d00     [5]             BCLR  6,_PTFD  0007          L7:        90:          LCD_SPI_SendChar(dat);  0007 cd0000   [6]             JSR   LCD_SPI_SendChar  000a          LA:        91:          while(LCD_SPI_GetCharsInTxBuf());  000a cd0000   [6]             JSR   LCD_SPI_GetCharsInTxBuf  000d 650000   [3]             CPHX  #0  0010 26f8     [3]             BNE   LA ;abs = 000a   92:          LCD_CD_SetVal();  0012 1c00     [5]             BSET  6,_PTFD   93:     }  0014 8a       [3]             PULH    0015 81       [6]             RTS   // I think I see the issue// the first var passed is stored in the X register// so when we make the second function call the adr var is equal to 0x00 so it clrs the X register// but that is actually erasing the original data we are passing.

 
As you can see if it wasn't for the ASM stepping function I would still be spinning my wheels trying to figure out why I am transmiting 0x00 all the time.  Now I think I know why but I am unsure of how to best fix it.
 
Any ideas?
Labels (1)
Tags (1)
0 Kudos
1 Solution
862 Views
v_dave
Contributor IV
Hello,
 
OK I know I need to treat warnings as errors.  The only excuse (and its a poor one) I have is this particular warning was buried in a bunch of "return parameter value ignored" (or something like that) warnings.  So I scrolled through them very quickly and missed it
 
I have since forced a full rebuild so that I can get a full listing af all my warnings and I have verified each one to make sure I don't have any issues like this again.
 
As for the way the vars were passed, that makes sense ANSI C defaults a var to an int if it is not defined and that is why the regiseters were getting loaded incorrectly.
 
Thanks again for the help.

View solution in original post

0 Kudos
6 Replies
862 Views
CompilerGuru
NXP Employee
NXP Employee
I don't really see the issue here. Some notes:

>0002 ad45     [5]             BSR   L49 ;abs = 0049
The L49 tells me that this is not directly calling another function but instead this is a local call to a common subexpression. So the first snippet is not directly related to the others.
I would suggest to disable this optimization with -onf in debugging, then the code gets usually more straight forward.

Also single character arguments are not passed in X, the are passed in A. X is only used with larger arguments (16 bit) or with multiple ones, but your snipper does not show other regs being used.

As tip I would also suggest that you should make sure no implicit parameter declaration happens, those are the usual source for such unexpected parameter passing bugs. Especially it is not legal to
have implicitly declared functions with char arguments/return types as ANSI expects all types to be at least int after propagation. There are warnings issued for all such cases, make sure you do not see any of those.

Daniel

862 Views
v_dave
Contributor IV
Hello,
 
OK, I found the header file I was missing and that seemed to correct the issue.  Thanks that was one of those things that you stare at and don't see but is obvious to someone else.
 
I still have a question about how the compiler works.  In the C manual (Compiler_HC08.pdf) it does state that the compiler passes parameters in the A & X registers.  If the A register is supposed to be for the first parameter how come the compiler was using the X register to pass the parameter?  I think I know what your answer will be but it seems to me that this could lead a developer down the wrong path tht the compiler has bug not that they forgot to include a header file.  I know read the warnings and I should see it but who actually believes that the warning messages are important? Only the Error messages matter ;o)
 
Before:
Code:
  116:      ghw_cmd(0x23);          //SET Duty=1/65  0004 ae23     [2]             LDX   #35  0006 ad41     [5]             BSR   L49 ;abs = 0049Here it is loading 0x23 into the X register

 
After I found that header file I was missing:
Code:
  116:      ghw_cmd(0x23);          //SET Duty=1/65  0005 a623     [2]             LDA   #35  0007 cd0000   [6]             JSR   ghw_cmdNow it is loading 0x23 into te A register as expected.

 Anyways thanks for the help and now I should be ble to move on to the next issue :smileysurprised:)
0 Kudos
862 Views
bigmac
Specialist III
Hello Dave,
 
I assume that what you observed is because an implicit parameter was assumed to be a (signed) 16-bit
value, so the LS byte would be passed in X.  You will probably find that the ACC is zeroed near the
beginning of the L49 code section.
 
I think it is important to investigate the reason for every warning given.  It is always possible that it will
lead to the incorrect code being generated by the compiler.  An error would be generated because the
compiler cannot continue, while a warning would be generated when the compiler can make an
assumption, and then continue with the compile.  The assumption may not be relevant.
 
Regards,
Mac
 


Message Edited by bigmac on 2008-02-22 06:04 AM
862 Views
CompilerGuru
NXP Employee
NXP Employee
The implicit parameter declaration is a warning only because this is legal in ANSI C.
The point is, as bigmac mentioned, the type of implicit parameters is deduced from the actually given arguments, and given the ANSI C rules of expressions they end up being at least int. So there is no legal way of an implicit parameter declaration of a function with a char parameter, but the compiler cannot issue an error for this case as he only sees the usage and not the declaration.
About the actual parameter passing, out of my mind the parameter passing is different for a single 16 bit argument for the HC08 and the S08. As the S08 has improves capabilities for using HX together, the compiler is using H:X if I remember right (really not sure).
Anyway, in the first pattern the BSR did jump to an internal label, while in the second path the actual function was called, so the two patterns really do not show the same. The first pattern compiled with -OnF would probably show more. Anyway, in C never use implicit parameter declarations, configuring this warning to an error is highly recommended.

Daniel
0 Kudos
863 Views
v_dave
Contributor IV
Hello,
 
OK I know I need to treat warnings as errors.  The only excuse (and its a poor one) I have is this particular warning was buried in a bunch of "return parameter value ignored" (or something like that) warnings.  So I scrolled through them very quickly and missed it
 
I have since forced a full rebuild so that I can get a full listing af all my warnings and I have verified each one to make sure I don't have any issues like this again.
 
As for the way the vars were passed, that makes sense ANSI C defaults a var to an int if it is not defined and that is why the regiseters were getting loaded incorrectly.
 
Thanks again for the help.
0 Kudos
862 Views
CompilerGuru
NXP Employee
NXP Employee
As tip. the "return value ignored" message can be seletively disabled, or the code can explicitly not use the return value by casting it to void, e.g.
(void)strcpy(buffer, "Hello");

Messages can be selectively disabled or moved to an error in the Messages dialog in the Compiler for HC08 preference panel.

Daniel
0 Kudos