jsolarski 94 Posted September 6, 2010 Share Posted September 6, 2010 This Delay function is for mspgcc, this is the one suggested by mspgcc to use instead of int i = 1237; while(1--); or int i; for (i = 0; i <1234; i++); mspgcc will usually remove delays like this thinking it is a wast of space. mspgcc suggest to use an inline function like this example taken from the mspgcc user guide. static void __inline__ msp_delay(register unsigned int n) { __asm__ __volatile__( " 1: \n" " dec %[n] \n" " jne 1b \n" : [n] "+r"(n)); } call this function when ever you need to do a short delay(or long one lol) example //"your code" msp_delay(15); //delay //"your code" you may be able to use this in CCS or IAR but I'm not sure, since I do not have the windows box to run those programs. bluehash and GeekDoc 2 Quote Link to post Share on other sites
moonshadow 2 Posted September 6, 2010 Share Posted September 6, 2010 I usually use #define GCC_BARRIER asm("":::"memory") GCC will not reorder reads and writes across GCC_BARRIER, will not retain values in registers across GCC_BARRIER (so globals etc. will be refetched), and will not optimise away loops containing a GCC_BARRIER, so int i; for (i = 0; i < 1000; i++) GCC_BARRIER; is a nice concise delay loop. JMLB 1 Quote Link to post Share on other sites
jsolarski 94 Posted September 6, 2010 Author Share Posted September 6, 2010 That looks great! thanks for the addition but what is the advantage of using the for loop with asm("":::"memory"); Im not too familiar with assembly, so could you explain what that assembly line does? my other question is how does the for loop look after its compiled? Quote Link to post Share on other sites
moonshadow 2 Posted September 6, 2010 Share Posted September 6, 2010 GCC's asm() directive takes assembly code, followed by lists of outputs, inputs and things that the compiler is to assume have become dirty. The statement asm("":::"memory") generates no code, but tells the compiler to assume that any state held in memory may have been mutated as a side effect. This leaves GCC unable to make assumptions about the contents of variables following this statement, preventing optimisations that rely on such assumptions. A for loop with that statement in the body generates assembly very similar to that in your post - the appropriate increment / decrement, a comparison if counting to a nonzero value, and a conditional branch. The advantage is readability - the bulk of your code remains in C, you don't have to sprinkle little bits of assembler everywhere every time you need to work around yet another compiler optimisation. Quote Link to post Share on other sites
jsolarski 94 Posted September 6, 2010 Author Share Posted September 6, 2010 its my turn to rtfm for gcc lol, since the mspgcc is not very clear on all of gcc just msp specific workarounds. but that does make sense, but i wont fully get it till i compare the 2 in the debugger or simulator and watch them run thanks for the info!! Quote Link to post Share on other sites
RobG 1,892 Posted January 14, 2011 Share Posted January 14, 2011 Why not just use intrinsic function? __delay_cycles(numOfCycles); // where numOfCycles is unsigned long or for a single cycle delays __no_operation(); // inserts NOP instruction zeke 1 Quote Link to post Share on other sites
NatureTM 100 Posted January 15, 2011 Share Posted January 15, 2011 Does __delay_cycles() just insert nops? If so, it really would have cleaned up my tv output code. Quote Link to post Share on other sites
gatesphere 45 Posted January 15, 2011 Share Posted January 15, 2011 Why not just use intrinsic function? __delay_cycles(numOfCycles); // where numOfCycles is unsigned long or for a single cycle delays __no_operation(); // inserts NOP instruction because __delay_cycles() isn't supported by MSPGCC. This delay function is for MSPGCC, as stated in the first post. Quote Link to post Share on other sites
RobG 1,892 Posted January 15, 2011 Share Posted January 15, 2011 My bad, didn't notice that In any case, I think some will find it useful. Quote Link to post Share on other sites
zeke 693 Posted January 22, 2011 Share Posted January 22, 2011 I have found it quite useful. It works wonderfully in CCS4. Thanks for the tip! Quote Link to post Share on other sites
RobG 1,892 Posted January 22, 2011 Share Posted January 22, 2011 Does __delay_cycles() just insert nops? If so, it really would have cleaned up my tv output code. It depends on how long the delay is and it is a combination of NOPs, JMPs, and loops. __delay_cycles(1); 0xF806: 4303 NOP __delay_cycles(3); 0xF808: 3C00 JMP (0xf80a) 0xF80A: 4303 NOP __delay_cycles(0x0F); 0xF80C: 120D PUSH R13 0xF80E: 432D MOV.W #2,R13 1_$2: 0xF810: 831D DEC.W R13 0xF812: 23FE JNE (1_$2) 0xF814: 413D POP.W R13 0xF816: 3C00 JMP (0xf818) 0xF818: 4303 NOP __delay_cycles(0xFFFF); 0xF81A: 120D PUSH R13 0xF81C: 403D 5552 MOV.W #0x5552,R13 1_$3: 0xF820: 831D DEC.W R13 0xF822: 23FE JNE (1_$3) 0xF824: 413D POP.W R13 0xF826: 3C00 JMP (0xf828) __delay_cycles(0xFFFFFFFF); 0xF828: 120D PUSH R13 0xF82A: 120E PUSH R14 0xF82C: 403D 3FFC MOV.W #0x3ffc,R13 0xF830: 403E 3FFF MOV.W #0x3fff,R14 1_$4: 0xF834: 831D DEC.W R13 0xF836: 730E SBC.W R14 0xF838: 23FD JNE (1_$4) 0xF83A: 930D TST.W R13 0xF83C: 23FB JNE (1_$4) 0xF83E: 413E POP.W R14 0xF840: 413D POP.W R13 0xF842: 4303 NOP Quote Link to post Share on other sites
zeke 693 Posted January 27, 2011 Share Posted January 27, 2011 I tried the for() loops and calls to __delay_cycle(n) but nothing was remotely predictable. I had to calibrate my g2231 before any sort of delay routine was reliable when the DCO was set to anything other than 1MHz. The O'scope revealed to me that, once calibrated, the __delay_cycle(n) routine was bang on with every number I threw at it. Yes, I realize that I'm using CCS4 and not mspgcc but I thought that this info would be useful to someone. jsolarski 1 Quote Link to post Share on other sites
GeekDoc 226 Posted January 27, 2011 Share Posted January 27, 2011 Yes, I realize that I'm using CCS4 and not mspgcc but I thought that this info would be useful to someone. Many of us here use CCS4. I don't have the motivation to move away from my IDE. Quote Link to post Share on other sites
pabigot 355 Posted March 10, 2013 Share Posted March 10, 2013 For archival purposes: mspgcc has supported __delay_cycles() for several releases. This is the preferred way to insert a short delay without risking compiler optimizations breaking it, and should work in all major toolchains (GCC, IAR, CCS). For long delays or to do something useful during the delay use the timer peripheral. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.