Technically, the term "intrinsic" with compilers normally means exactly that: something that looks like a function, but for which the behavior is internally defined by the compiler which is allowed to optimize it in whatever way is consistent with the semantics. There's no requirement that it follow calling conventions, because it's not really a function.
For gcc, it's a bad idea to reference specific registers in the output template (e.g., asm("push r15")) because gcc isn't aware that r15 is being referenced. In particular, if that appears in an inline function, the fact that r15 is normally used for a parameter might cause the parameter to be eliminated entirely, if there's no other reference to it.
I'm not entirely clear what you're trying to do, but for mspgcc what you originally had for AVR is probably pretty close (an output template that does not specify a particular register, and an operand string that ensures whatever you pass in gets placed into a register before the asm is executed). But put it in a #define instead of an inline function, in case the compiler choses not to inline the function and you end up pushing something onto a call frame that gets discarded. Something like the following:
You might want to look at the C compiler that CCS V4 uses. I think it is Version 3. The
calling convention with CCS 'C' is that the first 4 integer arguments to a c function are
passed in R12-R15. Arg1 is R12 and arg4 is R15 ( at least for integer arguments)
Seems like you should be able to push R12 instead of using R4.
I've been looking for a way to run the msp430 with accurate MHZ speeds. In talking
with NatureTM on IRC, he mentioned that he had used a crystal oscillator ( ECS-100A-160 ) successfully
with his msp430g2231. He didn't have the exact code he used but he helped me recreate this snippet.
I didn't have a crystal oscillator but I did have an ATTiny84 lying around that I put on a breadboard.
I reprogrammed the ATTiny84 fuses so its CLKOUT fuse bit was enabled. The ATTiny is using an external
12MHZ crystal. This is fairly accurate, when you enable the CLKOUT fuse, avr outputs the
CPU clock on that pin as a square wave. I connected that pin to the XIN on my msp430g2231
and left XOUT unconnected.
I'm not sure if this is going to damage my g2231 as the specs say you should only feed it low
frequency external square waves from 10k - 50k. So don't expect this to actually work. I'm
just passing along what I've discovered.
https://gist.github.com/954778
-rick
//***********************************************************
// runfast.c - Using 12MHZ external square wave clock as LFXTCLK
// source MCLK/SMCLK from 12MHZ wave and blink led
// at 60Hz
//
// Use an external clock ( I'm using an attiny running at 12.00 MHZ
// with the CLKOUT fuse enabled ) as the MCLK/SMCLK for the MSP430.
// I've been told you could also use an external oscillator like an
// ECS-100A-160. I ordered some of these to verify.
//
// LFXT1 oscillator logic level square wave input frequency, LF mode
//
// XIN - external clock in from attiny CLKOUT pin ( set avr fuse to get clock )
// XOUT - NC
// P1.0 - led on until OSCFault cleared
// P1.4 - SMCLK frequency, measuer with multimeter/oscope
// P1.6 - 60Hz led flash, measure with multimeter/oscope
//
//***********************************************************
#include
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR = BIT0 | BIT6 | BIT4; // P1.0 and P1.6 output, P1.4 SMCLK frequency
P1SEL = BIT4; // P1.4 output SMCLK on P1.4, measure with multi meter
P1OUT = BIT0; // red LED on until OSCFault is cleared
DCOCTL = 0x00;
BCSCTL2 = SELM_3 + DIVM_0 + SELS + DIVS_0; // MCLK Source Select 3: LFXTCLK
// MCLK/1 SMCLK/1 SMCLK LFXTCLK
BCSCTL1 |= XTS; // XTS
BCSCTL3 = LFXT1S_3 | XCAP_0; // LFXT1 = 12MHZ crystal, No Capacitor
// not sure if this is needed
while(IFG1 & OFIFG) {
IFG1 &= ~OFIFG; // Clear OSCFault flag
_delay_cycles(10000); // delay for flag and visibility
}
P1OUT = 0; // red LED off
__bis_SR_register(SCG0); // Stop DCO, we just use the LFXT1 which is
// actually running at 12MHZ
while(1) {
P1OUT ^= BIT6; // green LED on, measure this, it should be 60Hz
_delay_cycles((12000000/60/2)-35); // 12MHZ, 60/2, 35 overhead clocks
}
}