This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TACCR0 settings for MSP430F2370 in TRF7960EVM Firmware code

Other Parts Discussed in Thread: TRF7960, MSP430F2370

Dear Texas Instruments engineers, I’m an Italian student working on TRF7960EVM for the thesis job.

 

I’m analyzing the “TRF7960 Firmware Source Code” ( released on 23 Feb 2009 ) that I’ve found on the site :  http://focus.ti.com/docs/toolsw/folders/print/trf7960evm.html

 

I can’t understand some lines in the firmware code involving Timer_A TACCR0 register setting.

 

Before discussing about Timer_A settings, let me make a preamble.

 

Preamble.1)

In the file main.c of the source code, the function OSCsel (0x00) let  MSP430F2370 do a clock switching from internal DCO clock at 1.1MHz (default DCO frequency at start-up, am I right?) to the external clock source from SYS_CLK pin (pin 27) of TRF7960 on Evaluation Module board. In fact, looking at the EVM schematic, pin 27 of TRF7960 is connected to Xin pin of MSP430F2370.

Nevertheless, the function OSCsel( ) in hardware.c shows these lines :

 

BCSCTL1 |= XTS + XT2OFF; // ACLK = LFXT1 HF-MODE XTAL

BCSCTL3 |= LFXT1S1;  // 3 – 16MHz crystal or resonator

BCSCTL2 |= SELM1 + SELM0 + SELS;

 

these lines means that ACLK clock is switched from default LFXT1 LF-mode to HF-mode and that LFXT1 clock source is from an external crystal/resonator in 3-16MHz range , and that MCLK =  SMCLK = this LFXT1 clock form crystal/resonator  : but in the related documents and in the schematic of the TRF7960EVM, wasn’t it said that MCU would operate with the external clock signal of 6,78MHz / 13,56Mhz from TRF7960? Anyway, someone on Texas Instruments forum has told me that the MSP430F2370 will operate well with this external clock from TRF7960 even if the instruction mentioned is BCSCTL3 |= LFXT1S1 instead of BCSCTL3 |= LFXT1S1 + LFXT1S0 as it would have been in my opinion…

What can you tell me about all that I’ve said in this first question?

 

Preamble. 2)

in main.c , to the function OSCsel ( ) has been passed the value 0x00 , but if another value had been passed, the DCO clock would have been used yet, but with a new value of frequency, as the instructions, in hardware.c, want :

DCOCTL |= DCO0 + DCO1 + DCO2;

BCSCTL1 |= XT2OFF + XTS + RSEL0 + RSEL1 + RSEL2;

So, DCOx = 7 and RSELx = 7 and there isn’t any explanation on MSP430F2370 Data Sheet about how to calculate DCO cloc freq. with this settings… is it in the range of 0,9-3 MHz ?

 

Preamble. 3)

All along the firmware code, it seems that there isn’t any other clock switch after OSCsel (0x00) in main.c;

This line in main.c : InitialSettings(), calls this routine defined in parallel.c that does set SYS_CLK pin output clock frequency = 6,78MHz

 

Pramble. 4)

Everytime TimerA is needed, the routine CounterSet ( ) in hardware.c is called : this routine does set for timerA clock source the ACLK clock divided by 8, so, if ACLK = LFXT1 clock = 6,78 MHz , then timerA clock source freq. is 847,5kHz

Everytime it is necessary to start timerA, the macro startCounter is called : this macro is defined in hardware.h on lines 72&73 in 2 ways , but one way as a comment :

 

line 72 : //#define startCounter TACTL |= MC0 + MC1          //start counter in up/down mode

line 73 : # definestartCounter  TACTL |=  MC1          //start counter in up mode

 

in my opinion, the comment in line 73 is wrong, by that instruction we set the “Continuos mode” for timerA not “Up mode” as it should do…

Anyway, let us assume that timerA operates in Up-mode whenever starCounter is found in firmware code.

 

Preamble is finished : 

 

all along the firmware,the programmer has been used to set, for example to obtain 20ms for Timer_A timeout :

 

countValue = count1ms * 20;

 

where countValue is a macro that defines TACCR0 reg. , count1ms is another macro that is a constant value of 847 (decimal value) defined on line 78 of hardware.h

To obtain 20ms of timeout , it is right to set TACCR0 = 847 in my opinion.

 

countValue = count1ms * 20;  can be found on line 127 of anticollision.c file in the Firmware Source Code to obtain 20ms of timeout,and that’s OK; but now, I can’t understand why on line 145 you’ve written :

 

countValue = 0x4E20;

 

in my opinion , this new different value for TACCR0 has a sense if , form line 127 to 145 , there has been some ACLK frequency change, and in my opinion there hasn’t been. It’s peculiar that in line 144 you have commented the  : countValue = count1ms * 20  instruction : did the programmer change his mind during firmware drawing up? Why?

In my opinion, all along the firmware execution , surely as regards ISO15693 firmware lines execution , but I believe that the same regards other protocols firmware lines implementation, there isn’t any clock changing so I can’t understand,again, why on line 346 of anticollision.c , there is :

countValue = 0xF000;/* 60ms for TIMEOUT */

 but  then on line 354 : countValue = count1ms * 60; /* 60ms for TIMEOUT */

and this last is the right instruction to obtain 60ms timeout , in my opinion.

Why countValue = 0xF000; has been set for 60ms Timeout?

 

The same problems I have on : line 152 on epc.c file + line 45,160,171,361,518,615 on 14443.c

 

I hope you can illuminate me about why isn’t ever used the instruction format :

countValue = count1ms * Y where Y = integer number

that is always right in my opinion.

 

A last question : the firmware line : __low_power_mode_off_on_exit();

 Is it an Interrupt Service Routine (ISR) that switches off any low power mode used in firmware execution whenever an Interrupt is arised to MSP430F2370?

As it seems to me,only LPM0 mode is used in TRF7960EVM firmware, a low power mode that switches off MCLK only, and that doesn’t change SMCLK and ACLK clock frequencies…

 

Thank you very much for paying attention to me, excuse me for the not-proper English and the “verbosity” of the questions, maybe it’s the only way to let you understand my problems.

  • The clock logic is switched to high frequency mode because this disables the internal capacitors for low-speed clock crystals.
    Setting LFXT1Sx is mostly unimportant when XTS=1 and an external source is used. It controls the driver strength which must be increased for higher-frequency crystals, but since the driver is not connected at all, only the pin capacitance is driven, resulting in a slightly higher current consumption, if any. It has no influence on the functionality.

    Setting DCOx=7 and RSEL=7 sets the DCO to its highest possible frequency. Modulation is disabled (sinc ethere is no higher tap to select).
    On some MSPs, this can well exceed the alowed operating range and will also flag an DCO OSC fault. I don't have the datasheet at hand, but for all MSPs, the range of the DCO for a given RSEL as well as the steps between RSEL and/or DCO TAPs vary from device to device. All you can do is guessing or calculating a best/worst case by the datasheet.

    TACTL|=MC1 indeed sets the timer to continuous mode, unless MC0 was already set. This instruction only sets the bit, it does not clear the other.
    I guess it makes no difference whether you let the timer run in up mode to TACCR0 and stop it when the interrupt comes, or let it count in continuous mode and stop it when the interrupt comes when TACCR0 is reached. In both cases the timer will be stopped at the TACCR0 value :)
    Using the continuous mode has an advantage: if TACCR0 is very small, it is possible that TACCR0 is hit a second time while you are still in the ISR (or maybe a different one) and have not stopped the timer yet. In continuous mode, this won't happen until the timer has exceeded the 16 bit range.

    Daniel San said:
    countValue = 0x4E20;
    To obtain 20ms of timeout , it is right to set TACCR0 = 847 in my opinion.


    With 847,5MHz, TimerA increments by 847,5 per millisecond. So 20*847=16940 is the way to get a 20ms timeout. The maximum is 77ms.

    The value 0x4e20 seems to indicate that this calculation had been done for a TimerA clock of 1MHz, which might be a relic from a previous design stage where an 8MHz quartz was used for XT1 instead of the external 6.3MHz.

    Looks like an adjustment to save some cents. After all, the old values will result in just 18% longer timeouts and are surely not breaking the code. It's nothing timing-critical. And whether you wait 20 or 24ms for a timeout makes no difference. The 20ms are a 'diced' value anyway. (0xf000 would be 61.4ms at 1Mhz, but looks nicer than 0xea60 and does the job too)
    But I undestand that it can be annoying to find this kind of inconsistend values/comments if one tries to understand code and not just use it. It's something that happens often even in the code samples.

    Daniel San said:
    I hope you can illuminate me about why isn’t ever used the instruction format :
    countValue = count1ms * Y where Y = integer number
    that is always right in my opinion.


    My guess is that count1ms has been added later (after it had been obvious that ACLK will not always be 1MHz) and not all (or just few) of the code has been properly ported, since the old code still 'did the job'.

    Daniel San said:
    A last question : the firmware line : __low_power_mode_off_on_exit();
     Is it an Interrupt Service Routine (ISR) that switches off any low power mode used in firmware execution whenever an Interrupt is arised to MSP430F2370?
    As it seems to me,only LPM0 mode is used in TRF7960EVM firmware, a low power mode that switches off MCLK only, and that doesn’t change SMCLK and ACLK clock frequencies…

    When an ISR returns, it restores the status register from stack, and with it the bits controlling the LPMs. So this intrinsic (a compiler-specific function) is used to alter the LPM-dependent bits on the stack before the ISR returns. So the status register will be restored without these bits set and main() will continue with the instuction after entering LPM.

    This special intrinsic (a non-C special speudo-instruction that causes the compiler to generate assembly code with functionality outside the C language) is used in an ISR if the ISR decides that it is time for the main code to wake up. I is possible that an ISR does not use it at all or only if certain other circumstances happen. It is used in the normal program flow (e.g. if inside an IF statement, it will only be executed if the condition is true). I guess in this case it will cause main() to continue after the timeout has expired.

    using this intrinsic outside an ISR makes no sense and will clobber the stack. There are other intrinsics, such as __bis_sr() or __disable_interrupt() which are used anywhere in code.

    If LPM0 is the only one used in the application, indeed everything else should be left untouched.

    There is a chance that the external clock signal, which sources MCLK and ACLK, is changed by an operation the firmware performs, or by any outside hardware activity. I don't know, as I don't know neither firmware nor hardware.
    If this is the case, the MSP won't notice (as this clock is its -only- reference for passing time), now can the firmware detect it. But maybe the firmware knows under which circumstances/at which point this happens and has been written to reflect this change. If it is not documented/commented, nobody can tell (but it is not likely)

    p.s.: don't apologize for your English. Only a fraction of the forum users are native-speakers and even those do not have a problem with us 'non-natives' (they're not so 'British', usually) :)
    And better be more verbose than wait for days until you get the answer 'what did you mean?'
    (If only the website would be faster - with three of four of them opened, my machine begins to crawl only)

  • Thank you very much for the answer, your suggestions are very useful !

**Attention** This is a public forum