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.

CCS/MSP430G2744: SPI in 3-pin configuration. What's the problem?

Part Number: MSP430G2744

Tool/software: Code Composer Studio

Goodmorning everybody!

Today I'm writing on the forum because I have some troubles with the settings of SPI communication, but I don't understand why it isn't working.

CONFIGURAZIONE_SPI is my .asm function to configure the SPI registers.

CONFIGURAZIONE_SPI:

					mov.b #0x19, P3OUT
					mov.b #0x1F, P3DIR
					mov.b #0x31, P3SEL
					bis.b #UCSWRST, &UCA0CTL1
					mov.b #(UCCKPL+UCMSB+UCMST+UCSYNC+UCMODE_0), &UCA0CTL0
					mov.b #UCSSEL_2, &UCA0CTL1
					mov.b #32, &UCA0BR0
					mov.b #0, &UCA0BR1
					mov.b #0, &UCA0MCTL
					bic.b #UCSWRST, &UCA0CTL1

(P3.0 is SCLK, P3.1 and P3.2 are unused, P3.3 is CS, P3.4 is SIMO, P3.5 is SOMI, P3.6 is DRDY, necessary for the RTD-to-Digital Converter MAX31865 and P3.7 is LEVEL_INPUT specific for my application).

As my configurations are ready, I start the communication writing 0x80 on the trasmit data buffer UCA0TXBUF, but when I debugged this code section I found that the UCA0TXIFG was already set (instead of being 0)

and also the UCA0RXIFG was set (but in the UCA0RXBUF there isn't any character received).

I also tried to view the SCLK, SIMO, SOMI and ChipSelect (on P3.3) on the oscilloscope, but nothing at all...

So I think that the communication doesn't start.

This is my function:

;/*Settaggi SPI pronti per essere inviati*/
AVVIA_CONV:		push.w R9
				clr.w  R9
				bic.b #BIT3, P3OUT
				nop
				mov.b #0x80, &UCA0TXBUF
				nop
				bit.w #FLAG_FILTRO5060, &FLAG_ATTIVAZIONI
				jeq	  FILTRO_50Hz
				mov.b CONREG_MAX60, R9
				br	  #TRASMETTI
FILTRO_50Hz:	mov.b CONREG_MAX50, R9
TRASMETTI:		bit.b #UCA0TXIFG, &IFG2
				jeq	  TRASMETTI
				mov.w R9, &UCA0TXBUF
TRASMETTI_412:	bit.b #UCA0TXIFG, &IFG2
				jeq	  TRASMETTI_412
				mov.b #0, R9
				mov.w R9, &UCA0TXBUF
TRASMETTI_41:	bit.b #UCA0TXIFG, &IFG2
				jeq	  TRASMETTI_41
				mov.b #0, R9
				mov.w R9, &UCA0TXBUF
TRASMETTI_51:	bit.b #UCA0TXIFG, &IFG2
				jeq	  TRASMETTI_51
				mov.b #0xFF, R9
				mov.w R9, &UCA0TXBUF
TRASMETTI_2:	bit.b #UCA0TXIFG, &IFG2
				jeq	  TRASMETTI_2
				mov.b #0xFF, R9
				mov.w R9, &UCA0TXBUF
TRASMETTI_3:	bit.b #UCA0TXIFG, &IFG2
				jeq	  TRASMETTI_3
				mov.b #0, R9
				mov.w R9, &UCA0TXBUF
TRASMETTI_4:	bit.b #UCA0TXIFG, &IFG2
				jeq	  TRASMETTI_4
				mov.b #0, R9
				mov.w R9, &UCA0TXBUF
TRASMETTI_5:	bit.b #UCA0TXIFG, &IFG2
				jeq	  TRASMETTI_5
				mov.b #0, R9
				mov.w R9, &UCA0TXBUF
TRASMETTI_54:	bit.b #UCA0TXIFG, &IFG2
				jeq	  TRASMETTI_54
				pop.w R9
				bis.b #BIT3, P3OUT
				ret

Is there something wrong in my code?

How can I solve this problem?

I hope someone colud help me and give some advice to resolve the issue and do a good job!

Thank you very much,

Kind Regards,

Maria Angela 

  • Hi Maria,

    Is there a reason you're using assembly language instead of C? There are SPI code examples written in C and assembly available in the TI Resource Explorer that I recommend checking out if you're having issues. But first I'd recommend reading through SPI section of the Solutions to Common eUSCI and USCI Serial Communication Issues on MSP430 MCUs application report.

    After looking through the code you've provided above, I don't see a reason why there would be no activity on the SPI bus after moving data into UCA0TXBUF. That's not to say that the code above is correct though. I have a few comments:

    1. The initial value of UCA0TXIFG is 1.
      1. This can be seen in section 16.4.9 of the User's Guide
    2. UCA0RXIFG will always get set after sending data
      1. This is because in SPI communication, data is received at the same time it is sent
    3. You'll need to clear the UCA0TXIFG in the IFG2 register after verifying it has been set
      1. A bit.b operation doesn't affect the value of the destination
      2. So once UCA0TXIFG is set, bit.b #UCA0TXIFG, &IFG2 will always set the C bit until the UCA0TXIFG flag is cleared

    Best regards, 
    Caleb Overbay

  • Hi Maria,

    Was the above information enough to help you solve your issue?

    Best regards,
    Caleb Overbay
  • Hi Caleb,

    Sorry for my so late answer, but in this period I wasn't able to reply on the forum.

    However, the info you gave me were helpful to understand better how the flags work. Thanks ;)

    At the moment I think I have a problem of communication with my slave, MAX31865 (RTD-to-Digital Converter) because when I have to read the temperature probes, after a specific conversion from the RTD value to a temperature value, I received some uncorrect values and I don't know where is the trouble!

    I searched the possible error and I changed my code many times during this last week to try every possibility that came up in my mind... And today, Monday 27th of November 2017 I'm still here to try to find a solution :(

    If there is someone who has experience with this device, I would realy appreciate some advice and ideas to finally have my SPI communication protocol work.

    I attached my code, in which you can find more explanation.

    void  configurazione_SPIprova() {
    	unsigned int Configuration_Write;
        P3DIR |= BIT0|BIT1|BIT2|BIT3|BIT4;
        P3OUT |= BIT4;
        P3SEL = BIT0|BIT4|BIT5;
        //P3REN |= BIT6;
        UCA0CTL1 |= UCSWRST;
        UCA0CTL0 |= UCCKPH+UCMSB+UCMST+UCSYNC; // 3-pin, 8-bit SPI master
        UCA0CTL1 |= UCSSEL_2; // SMCLK
        UCA0BR0 |= 32; // /32
        UCA0BR1 = 0;
        UCA0MCTL = 0; // No modulation
        UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
        Configuration_Write = 0x80;
        P3OUT &= (~BIT3); // Select Device
        while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
        UCA0TXBUF = Configuration_Write; // Send 0x80 over SPI to MAX31865 to write on its internal Configuration_Register
        while (!(IFG2 & UCA0TXIFG));
        UCA0TXBUF=0x91;		//Write in the Configuration_Register to set VBias, Conversion Mode and Filter's Frequency bits
        REG_MAX31865[0]=UCA0TXBUF;		//Store the value in an array
        P3OUT |= (BIT3); // Unselect Device
        P3OUT &= (~BIT3); // Select Device
        UCA0TXBUF=0x83;		//Send the address of the next register I want to write
        UCA0TXBUF=0xFF;
        REG_MAX31865[3]=UCA0TXBUF;
        P3OUT |= (BIT3); // Unselect Device
        P3OUT &= (~BIT3); // Select Device
        UCA0TXBUF=0x84;
        UCA0TXBUF=0xFF;
        REG_MAX31865[4]=UCA0TXBUF;
        P3OUT |= (BIT3); // Unselect Device
        P3OUT &= (~BIT3); // Select Device
        UCA0TXBUF=0x85;
        UCA0TXBUF=0x00;
        REG_MAX31865[5]=UCA0TXBUF;
        P3OUT |= (BIT3); // Unselect Device
        P3OUT &= (~BIT3); // Select Device
        UCA0TXBUF=0x86;
        UCA0TXBUF=0x00;
        REG_MAX31865[6]=UCA0TXBUF;
        P3OUT |= (BIT3); // Unselect Device
    }
    
    void LetturaSPI_Prova() {
    	unsigned int Configuration_Read;
        P3OUT &= (~BIT3); // Select Device
        Configuration_Read=0x00;
        while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
        UCA0TXBUF = Configuration_Read;
        while (!(IFG2 & UCA0TXIFG));
        UCA0TXBUF=0x01; //This is the read address I need to read
        RTD_MSB=UCA0RXBUF;		//I store the value in RTD_MSB
        UCA0TXBUF=0x02;
        RTD_LSB=UCA0RXBUF;
    
    
        RTD=(RTD_LSB| (RTD_MSB<<8)); //I unify MSB and LSB to obtain a 16-bit value
        P3OUT |= (BIT3); // Unselect Device
    }
    
    void Get_Temperatura() {	//Finally I do the conversion from RTD (resistance value) to the temperature, as written on MAX31865 datasheet
    	unsigned int ADC_CODE;
    	unsigned int temperatura;
    	ADC_CODE=(RTD>>1);
    	temperatura=(ADC_CODE/32)-256;
    }
    

    Thank You very much for the attention,

    Best Regards,

    Maria Angela

  • Hi Maria,

    Just to confirm, you are able to send and receive data via the SPI interface but the data you are receiving back from the MAX31865 is not what you expect?

    Can you probe the SPI bus with a logic analyzer and verify that the data you expect to send to the MAX31865 is actually ebbing sent?

    Best regards,
    Caleb Overbay
  • Good Morning Caleb!
    Yes, I confirm everything you said. I'm able to send and receive data via SPI but data aren't what I expect.
    I noticed, probing the comunication with the oscilloscope, that data I read from my MAX31865 could be probably shifted by 1 bit right but I really don't know how it is possible if my configuration for SPI is correct (as I suppose).

    Here is my code(modified).

    I also have another question: why if I try to set 4-pin mode SPI comunication it doesn't work?

    With the 3-pin mode I have something like a comunication, but with 4-pin mode... anything, everything is sleeping!

    Hope to have your advice and ideas to solve these strange problems.

    Thank You very much,

    Best Regards,

    Maria Angela

    int main(void) {
    	WDTCTL = WDTPW | WDTHOLD;	//watchdog_disable();
    /* Inizializzo lo stack pointer al valore 0x5FF in fondo alla RAM */
    	__asm (" MOV.W   #0x0600,SP");
    	clear_RAM();
    	delay_watchdog (wdt_delay);
    	watchdog_enable();
    	configurazione_iniziale();
    	display_initialization();
    	configurazione_SPI();
    	trasmissione_CONFIGURAZIONI();
    	FREE=0; //Is a counter linked with 100ms timer
    	while (1) {
    		 	watchdog();
    		 	if(FREE>5) { //Wait 500ms
    			Lettura_SPI();
    			FREE=0;
    		 	}
    	}
    }
    
    void configurazione_SPI() {
        P3DIR |= BIT0|BIT1|BIT2|BIT3|BIT4;
        P3OUT |= BIT4;
        P3SEL = BIT0|BIT4|BIT5;
        P3REN |= BIT6;
        UCA0CTL1 |= UCSWRST;
        UCA0CTL0 |= (UCCKPH+UCMSB+UCMST+UCSYNC); // 3-pin, 8-bit SPI master
        UCA0CTL1 |= UCSSEL_2; // SMCLK
        UCA0BR0 |= 32; // /32
        UCA0BR1 = 0;
        UCA0MCTL = 0; // No modulation
        UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
    }
    
    void trasmissione_CONFIGURAZIONI() {
    	unsigned int Configuration_Write;
        Configuration_Write = 0x80;
        P3OUT &= (~BIT3); // Select Device
        UCA0TXBUF=(Configuration_Write);	// Send 0x80 over SPI to MAX31865 to write on its internal Configuration_Register
        while (!(IFG2 & UCA0TXIFG));
        UCA0TXBUF=CONREG_MAX50;		//Write in the Configuration_Register to set VBias, Conversion Mode and Filter's Frequency bits
        while (!(IFG2 & UCA0TXIFG));
        UCA0TXBUF=0x00;
        while (!(IFG2 & UCA0TXIFG));
        UCA0TXBUF=0x00;
        while (!(IFG2 & UCA0TXIFG));
        UCA0TXBUF=0xFF;
        while (!(IFG2 & UCA0TXIFG));
        UCA0TXBUF=0xFF;
        while (!(IFG2 & UCA0TXIFG));
        UCA0TXBUF=0x00;
        while (!(IFG2 & UCA0TXIFG));
        UCA0TXBUF=0x00;
        while (!(IFG2 & UCA0TXIFG));
        UCA0TXBUF=0x00;
        while (!(IFG2 & UCA0TXIFG));
        loop_delayREAD();
    
        P3OUT |= (BIT3); // Unselect Device
    }
    
    //loop_delayREAD is an asm function for a little delay
    loop_delayREAD:	mov.w	#0x20, R4
    loop_delay:	dec R4
    		jnz loop_delay
    		ret
    
    void Lettura_SPI() {
    	unsigned char count;
    	unsigned char var[8];
        Configuration_Read= 0x00;
        P3OUT &= (~BIT3);
        loop_delayREAD();
        UCA0TXBUF=0x00;
        while (!(IFG2 & UCA0TXIFG));
        UCA0TXBUF=0x00;
        while (!(IFG2 & UCA0TXIFG));
        for(count=0; count<8; count++) {
        	UCA0TXBUF=(0x00+count);
        	while (!(IFG2 & UCA0TXIFG));
        	var[count]=UCA0RXBUF;
        	}
        	loop_delayREAD();
        	P3OUT |= (BIT3);
        }
    
    /*var[1] and var[2] should be my RTD_MSB and RTD_LSB respectively but what I read isn't correct*/
    
    

  • Hi Maria,

    I apologize for the late reply. I reviewed your code and it doesn't seem to be complete. There are a few functions called in main() that aren't present in the rest of the code.

    If your data looks like it's shifted you may not have the correct clock phase selected. You need to ensure that the MSP430 and the slave device agree on when data is OK to read and when data is being changed. This is covered in more detail in Solutions to Common eUSCI and USCI Serial Communication Issues on MSP430 MCUs

    Best regards, 
    Caleb Overbay

  • Good Morning Caleb,

    Don't worry about it!

    Yes, I attached you only a little piece of my code because my project is becoming pretty big.

    However I'm very happy to tell you that I tried to experiment with the clock phase and finally I received and transimit the data correctly.

    Thank you very much for your reply. I will read the document in the link you highlight in the message soon.

    Have beautiful Christmas Holiday and a fantastic New Year's Eve!

    Best Regards,

    MariaAngela

**Attention** This is a public forum