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.

MSP432 Driverlib Demos all 3Mhz -- problems with 48Mhz, SMCLK, and I2C

Other Parts Discussed in Thread: ENERGIA

I have been using the MSP432 at a clients request for a couple months. Initially, I got everything I needed to work based on the examples (ADC, timers, interrupts, UART, and SPI) -- but didn't need to I2C, so left it for another day.

Now, I need the I2C and the examples all run at 3MHZ in the system_msp432p401r.c so I change the 3000000 to 48000000 in the file, and the conditional compilation should take care of the rest (I am using the vanilla system_msp432p401r.c file). 

My problem is that the demos all run in 3Mhz mode, so when you pump the processor to 48Mhz, everything breaks on I2C, I set the config up correctly as below:

// I2C master configuration for EUSCI_B @ 100Khz
const eUSCI_I2C_MasterConfig i2cConfig100Khz =
{
        EUSCI_B_I2C_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
	48000000,                                                                    // SMCLK = ??
        EUSCI_B_I2C_SET_DATA_RATE_100KBPS,      // Desired I2C Clock of 100khz
        0,                                                                                     // No byte counter threshold
        EUSCI_B_I2C_NO_AUTO_STOP                             // No Autostop
};


// I2C master configuration for EUSCI_B @ 400Khz
const eUSCI_I2C_MasterConfig i2cConfig400Khz =
{
        EUSCI_B_I2C_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
	48000000,                                                                    // SMCLK = ??
        EUSCI_B_I2C_SET_DATA_RATE_400KBPS,      // Desired I2C Clock of 400khz
        0,                                                                                    // No byte counter threshold
        EUSCI_B_I2C_NO_AUTO_STOP                          // No Autostop
};

I run the demo and it doesn't work anymore properly.

Now, I have read in the data sheet that the SMCLK as the source for the I2C has a max of 12/24 MHZ depending on the vcore. That's great, but I am not sure how to decrease the SMCLK divider without resorting to looking up dividers, PLL settings etc. Usually, there is a clock setting tool from most ARM vendors, that you make changes and then plug the output code into the analogous system_msp432p401r.c file, but there is no such tool with MSP432.

So, I have everything working at 3Mhz, and I can even get things working at 12Mhz for the system_clock by fudging the values in the above config, but what I really need to do is SET SMCLK divider, so that its 12/24Mhz when the system_clock is 48Mhz.

If anyone has dealt with this, did you solve it and am I missing something? Is there a tool or easier way to set these clock dividers?

I am not sure why the author Thomas of the demos ran everything at 3Mhz for I2C especially, since it would be nice to see HOW to make the changes and consider the importance of the SMCLK constraint to 12/24Mhz -- seems like the demos avoided this issue and didn't deal with them by running SLOW.

I have spent too many hours trying to figure this out, client is about to punt on MSP432 and pick ST, Freescale, or Atmel, so I really need a clear solution to this and how best to set clocks in a safe way, especially the SMCLK -- I would have thought the system_msp432... file would do this, but as I look at the code, I see no mention of SMCLK, just voltages, the flash wait states, and a few other things, but there are no "smarts" in the code to deal withe SMCLK and setting it correctly.

Alas, what is SMCLK set to by the default system_msp432p401r file? Does it change with changing the system_clock speed? If so, where?

Bottom line, I have I2C working slow, I just need to know what I need to do to address 48Mhz and SMCLK as the clock source for I2C which has a limit of 12/24 mhz.

Help!

Thanks,

Andre'

  • Andre,
    The SMCLK is not configured in the system_msp432p401r file. The default value of the SMCLK divider is defined is the reset value as defined in the TRM. Specifically within the system_msp432p401r file is the following (taken from CCS) with my additions to set the SMCLK divider. I think there is an issue with the wait state settings and modified those as well.

    #elif (__SYSTEM_CLOCK == 48000000) // 48 MHz
    // Switches LDO VCORE0 to LDO VCORE1; mandatory for 48 MHz setting
    while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
    PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_1;
    while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));

    // Switches LDO VCORE1 to DCDC VCORE1 if requested
    #if __REGULATOR
    while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
    PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_5;
    while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
    #endif

    // 1 flash wait state per Section 5.8 SLAS826E for Rev C. silicon
    FLCTL->BANK0_RDCTL &= ~FLCTL_BANK0_RDCTL_WAIT_MASK;
    FLCTL->BANK0_RDCTL |= FLCTL_BANK0_RDCTL_WAIT_1;
    FLCTL->BANK1_RDCTL &= ~FLCTL_BANK1_RDCTL_WAIT_MASK;
    FLCTL->BANK0_RDCTL |= FLCTL_BANK1_RDCTL_WAIT_1;

    // DCO = 48 MHz; MCLK = source
    CS->KEY = CS_KEY_VAL; // Unlock CS module for register access
    CS->CTL0 = CS_CTL0_DCORSEL_5; // Set DCO to 48MHz
    //CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK);
    CS->CTL1 = CS_CTL1_SELM__DCOCLK; // Select MCLK as DCO source
    /*
    * Establish SMCLK, DCO/2
    */
    //CS->CTL1 &= ~(CS_CTL1_SELS_MASK | CS_CTL1_DIVS_MASK);
    CS->CTL1 |= CS_CTL1_SELS__DCOCLK | CS_CTL1_DIVS__2;
    /*
    * End SMLK and MCLK dividers
    */
    CS->KEY = 0;

    // Set Flash Bank read buffering
    FLCTL->BANK0_RDCTL |= (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
    FLCTL->BANK1_RDCTL |= (FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
    #endif

    Additionally there are examples for setting the clock system using the driver library.
    dev.ti.com/.../

    My understanding is that Keil has this functionality with the MSP432. Let me know if you have additional questions.

    Chris
  • LOL -- thanks Chris -- I actually bit the bullet and went into the datasheet/reference manual, figured out the SMCLK, dividers, and how to set the bits in the clock system, and wrote a function to do that, I just can't believe there isn't a tool or at least excel spread sheet to do this. There is one for the baud rate generator which is a lot less complex then the ENTIRE clock tree here:

    software-dl.ti.com/.../index.html

    There should be a similar tool for clocking that generates C code you copy and paste into the system file... At least that's what the competitors have to save us time.

    So, I have the clocking working and SMCLK dividing down and staying within its limits at 12Mhz, now things are working!

    Now, my problem is the horrid support for I2C in general. I am all for bit banging and writing drivers. But, I don't have time to write the I2C drivers, and driverlib has nothing, but very low level functions (as you know), I have written an interrupt based I2C writebytes function now, and it works mostly, although seems the terminus flags for ack, nack, this and that are not accurate or always on time, but readbytes is more complex and I really don't feel like wasting more client hours figuring out the many side effects and problems others are having/had getting I2C read to work on these forums. I see everything from register level versions to versions that try and use driverlib all painful.

    This is a HUGE oversight for TI, they need to supply basic I2C write, read, functions, so we don't have to write them, since EVERYONE is going to have to do this -- so every customer has to write I2C functions? This is crazy -- 

    I want to focus my driver time on writing my camera driver or LCD driver, etc. not I2C digging into registers and hunting thru forums to see what others have found as bugs, side effects, etc. as they did this -- 

    Sadly, I can't seem to find any open source or anything for that matter I2C libraries that someone has written and tested -- so I can put this project to bed.

    If you know of a library that has the basic I2C writebytes, and readbytes functionality PLEASE point me in that direction...

    Andre'

  • Andre,
    You may already be aware of these, but here is what is available through driverLib:

    dev.ti.com/.../group__i2c__api.html

    dev.ti.com/.../

    Regards,
    Chris
  • Chris,

    Yes, the function API I have seen it of course, I was trying to avoid digging into it and wanted something higher level. You know the drill, even when you use something like this, you end up digging into the functions to find bugs, bit flags that aren't set, side effects, etc. sigh.... Anyway, thanks for the reminder, I guess I am doing this the hard way --

    I am a bit surprised at the lack of community support for this processor though? I wouldn't use it for my products since its too slow, but its a really nice processor, nice free tool, decent libs except for things like missing I2C high level functions. But, all in all I can't believe I can't find 100 web sites that have people writing drivers and more robust libs. Of course, there is energia, but that's more for arduino folks, that don't need to debug and write massive code.

    Anyway, I will give this a try and see if I can get it going in a few hours which I doubt, more like a few days is really needed to debug and get this working usually when you have to go this low...

    Andre'
  • Hi Andre, let me try to address a number of the excellent comments you made throughout this thread. 

    Andre Lamothe said:
    I don't have time to write the I2C drivers, and driverlib has nothing, but very low level functions

    We actually have I2C drivers for the MSP432 based on TI-RTOS (you can find details here). As a side note, we are planning a fairly big update to our drivers later this year.

    Andre Lamothe said:
    I actually bit the bullet and went into the datasheet/reference manual, figured out the SMCLK, dividers, and how to set the bits in the clock system, and wrote a function to do tha

    The DriverLib functions you (and Chris) mentioned provides an easy set of functions for setting up the clocks. As you found, only the the main system clock (MCLK) is setup in the standard "SystemInit()" function; the remaining clocks are left in their default state. If you check the MSP432 workshop solution files, you will find an example for setting all the clocks in the clocking chapter lab exercises.

    Andre Lamothe said:
    I am a bit surprised at the lack of community support for this processor though? I wouldn't use it for my products since its too slow, but its a really nice processor

    This is a fairly new MCU having just been released to production this summer. If our E2E forum questions are any indication, we expect you will see lots of community activity over the coming  year.

    Thanks for taking the time to ask questions and provide suggestions. Please keep this feedback coming!

    Take Care,
    Scott

  • Andre,

    The MSP432 has an eUSCI module like some MSP430s do. TI provides an SMBusLib driver stack that could be adapted. Not sure if that saves you any time vs rolling your own, but an option I though I'd throw out there.
  • Thanks -- I actually wrote my own driver, had I2C write working very well, and was in the middle of I2C read, then found thru googling, a driver that isn't part of any of the libraries, but was made by TI. I found a link to the functions and with a few changes, they worked, so I changed to them and got the I2C working and gave it to the client and got everything working -- The link to the source was found by searching google and on this forum, someone posted a link, or link to link and I found them and got them working AFTER I had mine 75% done -- :) 30 hours I spent researching the I2C registers and trying to get everything working, basically threw away, but I guess now I know how these work on this IC, so its not all a loss.

    Anyway, hopefully this new release will be more robust and have more to it. Plus, I found a lot of bugs in all the demos for the MSP, code bugs as well as a lot of copy and paste bugs with comments. I could get thru it, but someone new to embedded that hasn't done it 30 years might get confused when the comments says "read" but the code does write :)

    Thanks -- everyone. Glad I got this working.

    Andre'

  • So which one did you use? reference please?

    I´m trying to get data from 9 Dof sensor LSM9DS1 and I can´t find any functions refering to subadress stuff in driverlib...

**Attention** This is a public forum