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.

problem of running tiva on 80 MHz

Other Parts Discussed in Thread: TM4C123GH6PGE, TM4C123GH6PM

I have the TM4C123FGH6PM controller. I have TivaWare 2.1.0. I try to start my simple program:

SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

freq = SysCtlClockGet();

Then I read value of freq variable and I have got a value of 66,666666 MHz, but expected value is 80 MHz. What is wrong?

As I see in RCC2 register, it looks fine:

SYSDIV2 = 2

SYSDIV2LSB = 0

USERCC2 = 1

DIV400 = 1

  • Hello Tankist,

    Can you check the register 0x400FE010 bits 15 to 12.  What is the value of these bits?

    Regards

    Amit

  • It has a value of 0x13332FFF, and a value of 12-15 bits is 0x2

  • Hello Tankist

    Since the bit value is 0x2 it would mean that the part will not work above 66MHz. Please look at the description of the register SYSCTL.DC1

    Regards

    Amit

  • Oops! And how can I recognize which controller has a 80 MHz speed instead 66 MHz speed when ordering?

    Why my controller has the 66 MHz speed if I read in datasheet that the maximum speed is 80 MHz?

  • Hello Tankist,

    I checked back and the bit SYSDIV2LSB should be set by the SysCtlClockSet function. This bit gives the half divider for 80MHz.

    Did you try writing this bit?

    Regards

    Amit

  • SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    freq = SysCtlClockGet();

    Might it be that your placement of "freq" is too soon in your program?

    SysCtlClockSet() is a massive function - may require more time for everything to "settle."

    A more "classic" means of properly confirming System Clock is via forcing a Timer into PWM mode - employing a reasonable Timer, integer divider (say 4) and then monitoring that Timer pin's (relatively low Z) output frequency.

  • Amit Ashara said:

    I checked back and the bit SYSDIV2LSB should be set by the SysCtlClockSet function. This bit gives the half divider for 80MHz.

    Did you try writing this bit?

    Hello, Amit. This is a part of device's datasheet (DS-TM4C123GH6PM-15033.2672  SPMS376 B):

    As I understood it is the same configuration as mine and I don't know why I need to change state of SISDIV2LSB.

  • cb1_mobile said:

    Might it be that your placement of "freq" is too soon in your program?

    It is not depend on moment of measurement.

    And I asked this question because in PWM mode I could not get the desired frequency.

  • Hello Tankist,

    I found out the issue. The issue is with the SysCtlClockGet function. In the function there is a read of the SYSCTL.DC1 register which overrides the computed value. Hence you will see 66MHz as the return value.

    To be on the safer side a ran timer in periodic mode with div by 10 toggle and I see 8Mhz on the GPIO, which tells me that the clock indeed is 80MHz.

    We will resolve this in the next TIVAWare Release. This issue is on TIVAWare 2.1.0 release and not in the previous release.

    Regards

    Amit

  • Amit, thanks a lot. I replaced usage of  this function to the fixed value and I've got a good result.

  • Amit Ashara said:
    there is a read of the SYSCTL.DC1 register which overrides the computed value.

    Good to see you two resolve this - good job - good teamwork.

    However - does this stated "override" via, "SysCtlClockGet()" actually impact the System Clock frequency?  Poster appears to have reported that the System Clock was impacted (i.e. lowered to 66MHz). 

    Clearly any "Get" of a variable should not cause that variable's modification!  (as that's the domain of a "Set" - warning should be loud/clear - should a simple "Get" cause such variable modification...)

  • Sorry, it's my fault. Actually microcontroller clocked at 80 MHz, but I used the SysCtlClockGet () function to set the frequency divider of PWM, which returns an incorrect result, causing the pulse frequency was wrong, and the situation looked as if the controller actually operates at 66 MHz.

  • Hello cb1_mobile,

    I agree with you. The Get must not cause a variable change based on override and is being corrected for the next TIVAWare release.

    Regards

    Amit

  • Amit,

    I just ran into the same problem (and fixed it before looking on here, LOL) on TM4C123GH6PGE, swapping from an older StellarisWare release to TivaWare (LM4F232H5QD was covered by StellarisWare). It looks like TivaWare is *CORRECT* in what it is doing, ie SYSCTL_DC1_MINSYSDIV_80 is correctly defined as 0x1000, but the problem lies with the part itself. If you inspect the TM4C123GH6PGE datasheet you find that Table 1-1 correctly shows the part maximum operating frequency as 80MHz, *BUT* when you look at the SYSCTL DC1 register definition (page 433 in my copy) you find MINSYSDIV for this part is 0x2000 which corresponds to a 66MHz part (minimum divider 3 not 2.5). Reading SYSCTL DC1 does indeed return 0x2000 which is wrong for the part. It should return 0x1000.

    I have fixed this in my local copy of TivaWare by recompiling it with the frequency limiting commented out and it works again (it wasn't there in StellarisWare anyway) - I guess the quickest (as in compiled code) way round it is to change a #define based on which part you're compiling for and have two veneer functions which pass a flag (unseen to the programmer) into the underlying real function as a workaround - it'll cost an extra MOV and a branch in a call and probably another16 bytes or so in the compiled library (since there will be two veneers, a compare in the function and a conditional branch round the frequency limiting code).

    Cheers,


    Pat.

  • Hello Patrick

    Yes, the issue is in the TIVAWare release 2.1.0 and as you mentioned that is correct thing to do which the next TIVAWare release will fix. Just to clarify this got introduced in 2.1.0 and was not there on any of the previous release including StellarisWare.

    Regards

    Amit

  • Hiya Amit!

    I've had a chance to think about this a little more and it is a little more complicated than it first appears :

    It all starts with a "bug" in SysCtlClockSet(). That call does no plausibility checking on the requested divisor - it doesn't check if it is valid for the part or not. You can call SysCtlClockSet() with SYSCTL_SYSDIV_2 on TM4C123GH6PGE and it applies this config to RCC and RCC2. It is a void function so it cannot report success or failure anyway - perhaps it should be redeclared as a ui32_t returning actual frequency achieved, so you could do :

    if (SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN) != 80000000) __die_horribly__or_try_something_else();

    The second "bug" is that the silicon does no correction. When you call SysCtlClockSet() with what are notionally "impossible" values, it puts that config into RCC and RCC2. The silicon does its best under the circumstances. A divisor of 2 "should" divide the 200MHz clock by 2, but that's not possible, so since it is running off the 200MHz clock it chooses a divisor of 3 to give 66.666MHz. It does NOT reflect this fact in reads of RCC and RCC2, instead it reports a divisor of 2.

    The third "bug" is that TivaWare 2.1.0 introduces a new plausibility checking *feature* in SysCtlClockGet() - rather than just accepting the RCC and RCC2 registers at face value, it checks whether they are possible, which seems like a good idea. There is, however, a bug in that code because it does not take into account whether the 200MHz or 400MHz clock is selected for division. By way of example, using SYSCLK_SYSDIV_2 tries to divide the 200MHz clock by 2, but since this exceeds the part rating it actually divides by 3. The new plausibility checking code would (were it not for bug #4 below) return 80MHz not 66M.666MHz under these circumstances.

    The fourth "bug" is in the silicon, so that even if the third bug was fixed, it would still return the wrong value because the part itself reports the wrong minimum divisor. The DC1 register reports a minimum divisor of 3, when in reality the part can cope with a divisor of 2.5 (ie 400MHz divided by 5). It therefore incorrectly believes the part cannot run faster than 66.666MHz and reports that value, regardless of whether the 200MHz or 400MHz clock is selected for division, for any SYSCTL_SYSDIV value of _2_5 or less. 

    There are probably two sensible approaches regarding how to fix this :

    1) Fix SysCtlClkSet() so it cannot set incorrect RCC and RCC2 values, remove the sanity checking from SysCtlClkGet() again and stipulate that the latter is only certified to return the correct value if the former was used to set the clocking in the first instance. NB: because of bug #4 above, it is not possible to use DC1 (without workarounds) in setting RCC and RCC2.

    2) Leave SysCtlClkSet() alone, and fix SysCtlClkGet() for bug #3 above to return the correct value using a workaround for bug#4 above. This would allow users to set RCC and RCC2 directly and expect SysCtlClkGet() to still return the correct value.

    Cheers,

    Pat.

  • Hello Patrick,

    Well written with a lot of thought behind it.

    1. The data sheet explicitly mentions the divider values to be used to get the required system clock frequency. The user can try to change the parameters cause it to lock at a very high frequency and brick the device. By correcting it, the user code may think that the system frequency is higher than what data sheet is mentioning and so any subsequent time based computations go for a toss. This is the prime drive behind no auto-correction.

    2. The SysCtlClockGet indeed is broken with the current implementation and as you mentioned it should take the SYSMINDIV and the actual RCC/RCC2 settings into account to compute the correct clock frequency which is what the next TIVAWare release will fix.

    Regards

    Amit

  • Hi Amit,

    i'm glad i found this topic. I agree with you, fixing SysCtlClockGet is all that needs to be fixed. Concerning the fix:

    1. Do you have a quick fix available that can be used just now?

    2. When is this next TivaWare release scheduled?

    Thanks,

    Janos

  • Hello Janos

    A quick fix will be to remove

        //
        // Limit the maximum clock to the maximum clock frequency.
        //
        if(ui32Max < ui32Clk)
        {
            ui32Clk = ui32Max;
        }

    from the sysctl.c file in SysCtlClockGet function and then compile the driverlib

    For the next release date for TIVAWare, I will get back to you.

    Regards

    Amit

  • @Patrick,

    Bravo - precisely crafted, stunningly detailed - each/every conclusion well documented & justified!

    And your "clipped Brit" (my guess) "Hiya" so much more "classy/respectful/friendly" than US kid's, endlessly repeated, "Hey Amit!" 

    You clearly made the time/effort to really understand this issue - then demonstrated the kindness to share here - for the benefit of many.  Very much appreciated - well done and thank you...

  • Amit Ashara said:

    A quick fix will be to remove

        //
        // Limit the maximum clock to the maximum clock frequency.
        //
        if(ui32Max < ui32Clk)
        {
            ui32Clk = ui32Max;
        }

    Hi Amit,

    thanks a lot!

    (For everyone who might be also still wondering, how the re-compiling of the driverlib works, i did it like this: Imported the project at "\TivaWare_C_Series-2.1.0.12573\driverlib\ccs" into CCS as "import existing CCS project". Changed the "sysctl.c" file according to Amit's suggestion, deleted the "Debug" folder (a "Clean Project" wasn't enough, apparently!), and built the project as usual. Because i did that, on a copy of the TivaWare folder, i copied the "\driverlib\ccs\Debug\driverlib.lib" file into the same location of the original, so that i didn't have to update the references to it in all my projects.)

    Cheers Janos

  • Amit (and everyone else on this thread),

    This error is actually more significant than it is getting credit for. 

    This problem in "SysCtlClockGet()" actually has major impact in other places when using TivaWare.  I independently found this problem (and *then* found this thread) when my previously working UART code stopped working.  Here's the code in my project:

    UARTConfigSetExpClk(HwBase, SysCtlClockGet(), rate_arg, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

    As is common in Stellarisware/Tivaware code, you call "SysCtlClockGet()" when setting UART parameters since it needs to know what the working clock is so the UART divisors can be set properly.  In my case, instead of handing it the proper 80 MHz, the call to "UARTConfigSetExpClk()" was being told the clock was 66.666 MHz.  Problem?  You bet.


    Like others in this thread,I decided to comment out the line that uses the incorrect max clock value.  Once I did that, everything started working right again.

    I believe this problem rises above "annoyance" and is actually a showstopper bug that TI should handle more loudly.  I am now behind a full day on a project for a client.  Neither of us is happy about this. 

    TI has the email of everyone who has downloaded the latest Tivaware.  Why don't they use that information to send an email to everyone who downloaded Tivaware 2.1, and let them know about this issue and the workaround of commenting out this line in sysctl.c. 

        if(ui32Max < ui32Clk)
        {
            //ui32Clk = ui32Max; // Comment this line out!
        }

  • Hello Peter,

    We do understand that such issues should have been addressed earlier and for a function like SysCtlClockGet the output of which is used for making divider and count value decision has a significant impact. We would definitely take in your suggestion.

    Regards

    Amit

  • heyy alll,

    what is the default frequency of operation of Tiva C TM4C123GH6PM.???

  • Hello Rajat

    At power up it is the 16MHz PIOSC. The MOSC and/or PLL from PIOSC or MOSC can be used by the user Code to get upto 80MHz.

    Regards

    Amit

  • After having stumbled on this problem today, I'd like to voice my utter disappointment in TI's policy of TivaWare releases.

    This is the second time in a couple of weeks that I've spent a whole day debugging my own code thinking there's an error somewhere, just to find out that the bug is actually in TI's code. Better yet, this time it's in code that has previously worked correctly.

    First of all, do you not have some sort of unit testing protocols set up for TivaWare? Bugs of this kind should never be able to leave the original developer's workstation.

    For something as profound as SysCtlClockGet giving out false information, I simply cannot believe that a 2.1.1 release doesn't yet exist. It's now October and the bug has been known since late March. I bet it's been fixed in your internal repositories since April.

    You need to push out these kind of fixes ASAP. If your version control system doesn't allow you to do this, then it's time to change the system for something better. And as Peter said, you have the means to contact users to tell them about these kind of problems. That's the least you should do.

    And for Amit/other TI Tiva team members - please don't take my rant personally. Instead, take it to your superiors. I've learned to prefer/trust TI over other MCU vendors lately, but things like this eat away that trust. Big time.

  • Hello Veikko

    As much as you value TI over other MCU vendors, we value our customers. I do understand a lot of folks stumbling upon the same issue (over and over again) and the frustration it can potentially build up.

    There has been a big gap (I acknowledge) between TivaWare release but rest assured we are trying hard to close in on the "irritant" bugs in software which are quite a few.

    Also I agree that there should be a better way to communicate to users. Do you agree a "Sticky Note" would be useful?

    Regards

    Amit

  • Hi Amit,

    I'm glad to hear that the team is working hard on fixing the bugs.

    Regarding my last post - which I admit was written in the frustration following the useless headbanging - I'd like to emphasize that I don't think big gaps between releases is bad per se, but what really annoys me is that TI has known about these bugs for quite some time and has totally failed to communicate them to the users.

    A sticky note on the forum would of course be better than nothing, but let's face it: the moment someone has to come to the forum to search for a solution to a problem caused by a bug in vendor-provided software (that the vendor knows about), it's too late. At that point a lot of time has probably already been lost in pointless debugging.

    What I would consider adequate is some sort of proactive notification system. Possible solutions include:

    • A "module" in Code Composer Studio called TivaWare Errata (just a text file with all known bugs since the last release), would check for updates every time CCS is launched, thus the user would get a notification of each update. (not a good solution for users of other IDEs, though)
    • Using the e-mail addresses gathered when the users request download permission for TivaWare, notify all users of bugs. A monthly digest for minor things, immediate notification for potentially nasty bugs.
    • Creating a mailing list eg. tivaware-users@something.ti.com, where all notifications regarding TivaWare (bugs, new releases, published howtos, etc) would be sent. Users would be encouraged to join the list when downloading TivaWare.

    On second thought, I would prefer the last solution. Actually, I wouldn't mind having such a list for each TI product I use / have designed into some project.

    Now that I got to speed, you could apply some sort of crowdsourcing scheme for finding bugs. The first one to report a specific bug on the forum gets a free launchpad or boosterpack, for example. A report would qualify for a "win" even if the bug had been previously discovered internal to TI, but not published through the notification system.

    I understand that some bean-counter -type people (usually higher up the command chain) don't like the idea of proactively broadcasting bugs/faults in the company products, but this is engineering and these kind of things are eventually discovered anyhow. Personally I trust a company/person more if they tell me right away if there's something I should know about, instead of me finding out by myself.

  • Hello Veikko,

    While the 2nd and 3rd options are good suggestions, and from an engineering perspective makes a lot of sense also to immediately notify users, there are potential legal hassles also.

    But I will still try to push the forum's agenda in the best manner I can.

    Regards

    Amit

  • Amit,

    I'm confused what sort of legal hassles are involved.  People and companies all across the globe create mailing lists to send information everyday, and I'm not aware of any legal problems preventing this from happening at TI as well. 

    Could you please elaborate what legal hassles are implied in creating a mailing list to send information to people who request that information be sent to them?

  • Hello Peter,

    Besides single users, there are other companies/vendor users that "may" prohibit broadcast mails to their official email id's. Hence the consideration. It is always safe to ask legal/infra before I commit to the forum.

    Regards

    Amit

  • I just spent several hours trying to figure out what's going on until I found this thread. 

    I agree with   suggestions.  TI should make more efforts to keep the designers up to date.  I can see more legal issues or loosing some customers for NOT keeping up-to-date the customers.

    For the 66.666MHz vs 80.000MHz issue, according to the data sheet (tm4c123gh6pm.pdf -> LaunchPad) it doesn't say anything about 66.6667MHz.  The value that SysCtlClockGet() is looking for is MINSYSDIV:

    "MINSYSDIV - System Clock Divider.  Minimum 4-bit divider value for system clock. The reset value is

    -  Value Description

         0x1 Reserved

         0x2 Specifies an 80-MHz CPU clock with a PLL divider of 2.5.

         0x3 Specifies a 50-MHz CPU clock with a PLL divider of 4.

         0x4 Specifies a 40-MHz CPU clock with a PLL divider of 5.

         0x7 Specifies a 25-MHz clock with a PLL divider of 8.

         0x9 Specifies a 20-MHz clock with a PLL divider of 10...."

  • Hello Yvonh,

    Firstly I understand your pain and it has been a tough task to get the data for all potential download users in one place. Good news there was there is no issue doing it (I mentioned legal checks). I will post an update the moment we get a system in place to do so.

    The MINSYSDIV works in two ways. One for the Whole number divider and the other for the fractional part. When using 80MHz the divider is set as 2.5 Thus the manner in which the software interprets it is 3 which generates the 66.66MHz value.

    Regards

    Amit

  • Hi Amit,

    I know this is an old post, but I just stumbled upon it.  I am running Tivaware 2.1.0.12573 with a clock of 80 MHz.  Interestingly enough, I discovered that I avoided the pain of the others in this post by using the ROM version of the call.  ROM_SysCtlClockGet() will return the correct value, while SysCtlClockGet() returns the 66.666666 value.  FYI...

    Cindy

  • Hello Cynthia,

    And the issue has been long fixed starting from TivaWare 2.1.1.71 release

    Regards
    Amit