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.

PORT MAPPING SMCLK TO P1.0 WITH MSP430F6736

hi guys! 

I'm new here !  (and super new MCUs programmer )

I read the user guide port mapping configuration part , but at my first project "Blinky" I wanted to be sophisticated and make the blink on port 1.0 using the SPI A0 CLK.

sure, i won't be able to notice the 'Blinking" led because of the high frequency, but my logic analyzer will :)

the logic was tested by me, managed to play a little with port 1 toggling.  

notice how I set UCA0CTLW0

that is my ccs code.

need your help please! 

#include <msp430F6736.h>

long i=0;

void main(void)
{
	  unsigned int count;
	    WDTCTL = WDTPW | WDTHOLD;

P1OUT = BIT0;
P1DIR = BIT6+BIT0;
PMAPKEYID=0x2D52;
	PMAPCTL=0x02;
	P1SEL=BIT6+BIT0;
	UCA0CTLW0=0b0110101110000010;
	P1MAP0 = PM_UCA0CLK;


while(1)
{


}

}

  • come on guys... you can do it :)
  • Hi hadar,

    I would recommend not using a binary value like that for writing UCA0CTLW0 as it makes your code quite difficult for others to understand, and makes it easy to have some shifted bit error. I'd recommend using the defined mnemonic values in the msp430 header file for the device, as these will match up with the bit names in the users guide and make it much easier to read your code. Some comments will also help make it much easier for others to understand what you are intending the code to do.
    From what I see your line of code is
    UCA0CTLW0 = UCCKPL | UCMSB | UCMST | UCMODE_1 | UCSYNC | UCSSEL_2 | UCSTEM;

    Something important here is that I don't think the SPI clock will actually start to output unless you write something to the TX buffer when you are in master mode like this - it will also only clock out one byte at a time, so if you want a continuous clock out you would need to keep putting bytes in the TX buffer. So you aren't going to see anything on the SPI clock unless you keep filling UCA0TXBUF with some dummy byte just to get it to output data (and with data, clock the clock line). Maybe this is what you are missing.

    Regards,
    Katie

    P.S. it might be easier (but still more in-depth than a basic software blinky) to port map a timer output here instead - then you could even use your timer to set a PWM and control the brightness of your LED, which you could observe, or even set it to a slow frequency observable by the eye.

  • Katie Pier said:
    Hi hadar,

    I would recommend not using a binary value like that for writing UCA0CTLW0 as it makes your code quite difficult for others to understand, and makes it easy to have some shifted bit error. I'd recommend using the defined mnemonic values in the msp430 header file for the device, as these will match up with the bit names in the users guide and make it much easier to read your code. Some comments will also help make it much easier for others to understand what you are intending the code to do.

    From what I see your line of code is

    UCA0CTLW0 = UCCKPL | UCMSB | UCMST | UCMODE_1 | UCSYNC | UCSSEL_2 | UCSTEM;

    Something important here is that I don't think the SPI clock will actually start to output unless you write something to the TX buffer when you are in master mode like this - it will also only clock out one byte at a time, so if you want a continuous clock out you would need to keep putting bytes in the TX buffer. So you aren't going to see anything on the SPI clock unless you keep filling UCA0TXBUF with some dummy byte just to get it to output data (and with data, clock the clock line). Maybe this is what you are missing.

    Regards,

    Katie

    P.S. it might be easier (but still more in-depth than a basic software blinky) to port map a timer output here instead - then you could even use your timer to set a PWM and control the brightness of your LED, which you could observe, or even set it to a slow frequency observable by the eye.

    Katie thank you for your help!

    I will add comments and set the code better ( the 16 bits :))

    I'll use the dummy byte and tell you if that worked.

    I really like your idea with the PWM

    and at the rigth time i will try to implement that.

  • Katie Pier said:

    Hi hadar,

    I would recommend not using a binary value like that for writing UCA0CTLW0 as it makes your code quite difficult for others to understand, and makes it easy to have some shifted bit error. I'd recommend using the defined mnemonic values in the msp430 header file for the device, as these will match up with the bit names in the users guide and make it much easier to read your code. Some comments will also help make it much easier for others to understand what you are intending the code to do.
    From what I see your line of code is
    UCA0CTLW0 = UCCKPL | UCMSB | UCMST | UCMODE_1 | UCSYNC | UCSSEL_2 | UCSTEM;

    Something important here is that I don't think the SPI clock will actually start to output unless you write something to the TX buffer when you are in master mode like this - it will also only clock out one byte at a time, so if you want a continuous clock out you would need to keep putting bytes in the TX buffer. So you aren't going to see anything on the SPI clock unless you keep filling UCA0TXBUF with some dummy byte just to get it to output data (and with data, clock the clock line). Maybe this is what you are missing.

    Regards,
    Katie

    P.S. it might be easier (but still more in-depth than a basic software blinky) to port map a timer output here instead - then you could even use your timer to set a PWM and control the brightness of your LED, which you could observe, or even set it to a slow frequency observable by the eye.

    Hi Katie

    it worked , i use the clock at port 1.0 and also transmit hex values at p1.3 (UCA0TXBUF) and the logic analyzer display them very well.

    here is the code : 

    do you have any idea why the clock frequency is 1MHz no matter if i use VLO,REFO,XT1? you can see at the code that i used VLO, supposed to be 10kHz but the clock on p1.0 is 1.5MHz, some "run" times even 1MHz.

    #include <msp430F6736.h>
    
    long i=0;
    
    void main(void)
    {
    	unsigned int i;
    	  char count=0;
    	    WDTCTL = WDTPW | WDTHOLD;
    
    P1OUT=0;
    P1DIR = BIT6+BIT0+BIT3;          //set outputs 
    PMAPKEYID=0x2D52;                //PMAP enable password
    PMAPCTL=0x02;
    
    UCA0CTLW0 |= UCSWRST;
    UCSCTL4|=SELS__VLOCLK;           //set SMCLK to VLO
    P1SEL|=BIT0+BIT3;                // make the data output and clock outpust peripheral
    P1MAP0 = PM_UCA0CLK;             // use A0 SPI terminal clock as output on p1.0
    
    UCA0CTLW0 |= UCCKPH|UCMSB|UCMST|UCSYNC|UCSSEL__SMCLK|UCSWRST; //initialize UCA0CTLW0 register 
    UCA0CTLW0 &= ~UCSWRST;           // 
    UCA0BRW=0x0000;                  // frequency scaler f/(UCA0BRW+1)
    
    for(i=0;i<100;i++);              //delay to let the clocks at the msp to initialize 
    
    while(1)
    {
    while(!(UCA0IFG & UCTXIFG));     // check if TX register is empty
    count++;
    UCA0TXBUF=count+0x30;            // send data
    for(i=0;i<5;i++);                // delay
    
    }
    }
    

  • Hi hadar,

    The code that you attached sets UCSCTL4 |= SELS__VLOCLK;

    The problem is, that at startup by default UCSCTL4 already has the SELSx bits set to SELS_4 = DCOCLKDIV. So what's happening here is that the existing value for SELSx(4) is getting OR-ed with the new value (1 for VLOCLK) and so it's really getting set to SELS_5 = "XT2CLK when available, otherwise DCOCLKDIV".  Because F6736 is a part where there is no XT2 available, this is getting set to DCOCLKDIV, which is typically somewhere around 1MHz at startup. You can observe this by pausing the debugger, and in the register view, going and looking at the UCSCTL4 register.

    So to fix this, you need to do either:

    UCSCTL4 &= ~SELS_7; //clear all UCSSELx bits

    UCSCTL4 |= SELS__VLOCLK;

    Or, you could do this:

    UCSCTL4 = SELM__DCOCLKDIV | SELS__VLOCLK | SELA__XT1CLK;

    (The reason we set SELM and SELA as well in this case is so that their current settings don't get cleared - if we did just UCSCTL4 = SELS__VLOCLK; it would clear your SELM and SELA settings because it writes to the whole register.)

    Regards,

    Katie

  • Katie Pier said:
    Hi hadar,

    The code that you attached sets UCSCTL4 |= SELS__VLOCLK;

    The problem is, that at startup by default UCSCTL4 already has the SELSx bits set to SELS_4 = DCOCLKDIV. So what's happening here is that the existing value for SELSx(4) is getting OR-ed with the new value (1 for VLOCLK) and so it's really getting set to SELS_5 = "XT2CLK when available, otherwise DCOCLKDIV".  Because F6736 is a part where there is no XT2 available, this is getting set to DCOCLKDIV, which is typically somewhere around 1MHz at startup. You can observe this by pausing the debugger, and in the register view, going and looking at the UCSCTL4 register.

    So to fix this, you need to do either:

    UCSCTL4 &= ~SELS_7; //clear all UCSSELx bits

    UCSCTL4 |= SELS__VLOCLK;

    Or, you could do this:

    UCSCTL4 = SELM__DCOCLKDIV | SELS__VLOCLK | SELA__XT1CLK;

    (The reason we set SELM and SELA as well in this case is so that their current settings don't get cleared - if we did just UCSCTL4 = SELS__VLOCLK; it would clear your SELM and SELA settings because it writes to the whole register.)

    Regards,

    Katie

    Thank you for the quick answer !

    I didn't even think about the default value and OR with it.

    Really appreciate all your help !

    Thanks again Katie you helped me alot ,

    Hadar :)

  • One thing to add regarding the original code: The port mapping controller has a timeout of a few MCLK cycles after setting the password. So it is a bad idea to set the password and then do some other things before doing the actual mapping. It is coincidence that the mapping worked. So line 16 should be moved to directly after line 13.
  • thanks for your answer,

    but i still wonder if that is what will occur 

    doesn't line 14 is supposed to let the KEY MAPPING be allowed at all times? 

  • No, it just allows future mapping operations (with new password required). If not set, this will only allow access to the PMM once, and further attempts will be ignored until next power cycle.
    Once you give the password, a timeout (32 MCLK cycles) starts. This timeout is reset on each access to a PMAP register, so the configuration may take any time. However, doing something else between will eventually cause a timeout and the PMAP will lock again. If by this time you didn't set PMAPRECFG, you'll lose access to the PMAP until next power cycle.
    In your case, you are still within the threshold. But your next code change (including an interrupt event) may break this and you never know why. That's why I mentioned this. Do your port mapping operations in one block with no other code in-between, and disable interrupts before (unless you are sure they are already disabled).

**Attention** This is a public forum