Use of F_CPU in .S source file

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have an app I'm working on that works ok with gcc 3.4.6, but 4.?.? will not work. One of the reasons is I have 90%+ asm code (no stack used, trying to minimize footprint on number of registers used). Anyway, I was going to just move it to an S file. Which works just fine, except I am unable to get F_CPU to work. It seems the hangup is the 'UL' tacked on the end. Is it possible to use the F_CPU that's already being passed to the assembler? (I think that's where its coming from).

Here's the C version-

#define BIT_DELAY ((uint8_t)(((F_CPU/DEBUG_BAUD)-9)/3))

Here's my attempt on the S version-

#define BIT_DELAY lo8(((F_CPU/DEBUG_BAUD)-9)/3))

if I get the F_CPU to a number without UL, it works ok.

I would like to use the already defined (or passed) F_CPU if possible (one less cpu freq define floating around). I am having trouble finding avr-as/gas examples that apply. I have been to binutils, etc., but am not coming up with anything.

I may just forget the S idea, and make it a 3.4.6 only deal.

Here's the app-
http://www.mtcnet.net/~henryvm/4...
don't know if will useful or not, but it is kinda neat to dump out the sram to see what's going on (when Dragon is sleeping).

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In order to use it inside an assembly expression, indeed, you have
to omit the UL. This should also be OK for normal C use, unless
the expressions where it is used are sloppy formed. But you could
always typecast it into (unsigned long) inside the C code anyway.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I should have added I'm letting Avr Studio do the makefile, I just fill in the cpu freq in the projects options (I have to pick my battles carefully, and makefiles are not my battle to fight).

I guess one more cpu freq define won't upset the order in the universe.

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> I should have added I'm letting Avr Studio do the makefile

Then just don't do this. There are other options as well (*), and it's commonly
known that AVR Studio is really only covering the most common cases with its
generated Makefile.

(*) Use an external Makefile, either generated by Mfile or from the WinAVR
template. Manually maintain it further.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

By the way, I think that Studio only passes a -DF_CPU=nnnnnUL to the comilation IF you have entered a number into the Frequency: box in the project configuration.... ...in fact I just confirmed that if you delete the number from that text field it no longer passes -DF_CPU so then you can go into the compilation options and add your own -DF_CPU=nnnnn there but without the UL suffix.

(but like Jörg said above you have to watch that wherever F_CPU is then used that it's not going to be demoted to an integer and it might be an idea to add a cast to any invocations of F_CPU)

Or you coud do the -DF_CPU thing on a per-file basis and use nnnnn for the .S files and nnnnnUL for the .c files - though I guess the intention here was to only have a single copy in one place - otherwise you might as well just define it separately in the .S file anyway

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, my latest plan for S file(s)- let Avr Studio do the makefile like I always do (if any options needed, I use the custom options tab). Fill in 'Frequency' in project options as always. C programs will see F_CPU with UL tacked on. Good. My S file will strip off the UL-

.set MY_FREQ,0 //init to 0

.irpc param,F_CPU //go through all 'characters' in F_CPU
  .ifnc \param,U //if not a 'U'
  .ifnc \param,L //and not an 'L'

  .set MY_FREQ,MY_FREQ * 10 //shift decimal number left

  .ifc \param,1 $ .set MY_FREQ,MY_FREQ+1 //add 1
  .endif
  .ifc \param,2 $ .set MY_FREQ,MY_FREQ+2 //add 2
  .endif
  .ifc \param,3 $ .set MY_FREQ,MY_FREQ+3 //add 3
  .endif
  .ifc \param,4 $ .set MY_FREQ,MY_FREQ+4 //add 4
  .endif
  .ifc \param,5 $ .set MY_FREQ,MY_FREQ+5 //add 5
  .endif
  .ifc \param,6 $ .set MY_FREQ,MY_FREQ+6 //add 6
  .endif
  .ifc \param,7 $ .set MY_FREQ,MY_FREQ+7 //add 7
  .endif
  .ifc \param,8 $ .set MY_FREQ,MY_FREQ+8 //add 8
  .endif
  .ifc \param,9 $ .set MY_FREQ,MY_FREQ+9 //add 9
  .endif

  .endif
  .endif
.endr 

.if (((MY_FREQ/DEBUG_BAUD)-9)/3)/256 //if number > 255
.error "BIT_DELAY will be greater than 255, you need to increase baud rate (DEBUG_BAUD)" //display error
.else
.set BIT_DELAY,(((MY_FREQ/DEBUG_BAUD)-9)/3) //is < 256, so create BIT_DELAY    
.endif

which leaves me with MY_FREQ same as F_CPU without the UL. Seems to be working.

I don't know anything about assembler directives, so was unable to come up with anything other than the above (looks a little brute force to me).

I could probably redefine F_CPU instead of using MY_FREQ, but thought I better play it safe for now (if F_CPU is passed to each 'compile file', whether its a c file or an S file, it 'should' be safe to redefine it in the S file? don't know yet)

Now I can have only one F_CPU floating around, and not have to worry about forgetting to change it in the S file(s) (no, its not a big deal, but it is nice).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

smaller version (that \param was being fussy earlier for some reason, so I just made it work with no calcs on the \param, but now its working right, I'm not sure what I was doing wrong earlier)-

.set MY_FREQ,0 //init to 0

.irpc param,F_CPU //go through all 'characters' in F_CPU
    .ifnc \param,U //if not a 'U'
    .ifnc \param,L //and not an 'L'
    .set MY_FREQ,MY_FREQ*10+\param //left shift,then add
    .endif
    .endif
.endr 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Pretty heavon cannon for the sparrow, I'd say. But if it works and makes you
happy to be able to use the AVR Studio Makefile as is, then fine with it.

Btw., you can also use the UL number within a C preprocessor conditional
still:

#if F_CPU < 1000000
  ;; some assembly code goes here
#else
  ;; something else here
#endif

as the preprocessor works on standard C numeric constants.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Pretty heavy cannon for the sparrow, I'd say
I agree. Although that could also be said about the F_CPU that's put in the makefile, I guess. Anyway, I'll never have to figure it out again, and I'll be set for life. Sparrow dead. Cannon back in the garage.

I'm not sure I could do what I wanted via the C preprocessor. I think I would need something the equivalent of a '.set' (at the very least).