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 SPI controller



Hello,

I am trying to communicate with a SPI device using UCB2 peripheral (but I can't get it work..).

During the debug session I found out the TXIFG bit from UCB2IFG never goes back to 1 after a data has been written to UCB2TXBUF. Some checks with a logic analyzer on the SPI signals show that no clock goes out P3.5.. At first, I thought the controller could be damaged, but changing from UCB0 to UCB2 does not change a thing.

Here is the way I setup the system clock (It works with other peripherals, but just in case something is wrong or missing..) :

CS->KEY = 0x695A;
CS->CTL0 = 0;
// setup MCU frequency
switch (freq) {
case FREQ_12_MHz:
	CS->CTL0 = CS_CTL0_DCORSEL_3;
	break;
case FREQ_48_MHz :
	CS->CTL0 = CS_CTL0_DCORSEL_5;
	break;
default :
	while (1) ;
}
//
CS->CTL1 = CS_CTL1_SELA_2 | CS_CTL1_SELS_3 | CS_CTL1_SELM_3;
CS->KEY = 0;

Here is the SPI initialisation I setup to use the SPI bus as master, 8bits data, at 400kHz bit-rate with the system clock (48MHz) as source:

// prepare for setup (reset the state machine)
UCB2CTLW0 = 0;
UCB2CTLW0 |= UCSWRST;
// load user settings
if (config->config & SPI_CONFIG_MASTER)
	UCB2CTLW0 |= UCMST;
if (config->config & SPI_CONFIG_DATA_LEN_7BITS)
	UCB2CTLW0 |= UC7BIT;
if (config->config & SPI_CONFIG_MSB_FISRT)
	UCB2CTLW0 |= UCMSB;
if (config->config & SPI_CONFIG_POLARITY_HIGH)
	UCB2CTLW0 |= UCCKPL;
if (config->config & SPI_CONFIG_CLKPHASE_1)
	UCB2CTLW0 |= UCCKPH;
// select clock (UCLK)
UCB2CTLW0 |= UCSSEL_0;
// compute counter value
UCB2BRW = 48000 / 400; // frequency unit: kHz
//
P3SEL0 |=  (BIT5 | BIT6 | BIT7);
P3SEL1 &= ~(BIT5 | BIT6 | BIT7);
// restart state machine
UCB2CTLW0 &= ~UCSWRST;
// enable interrupts
UCB2IE |= UCTXIE;
UCB2IE |= UCRXIE;

I use the following function to perform write/read on the SPI bus:

uint8_t spi_transfertbyte (uint8_t data) {
// waits until TX buffer is ready while (! (UCB2IFG & UCTXIFG)) ; UCB2TXBUF = data; // waits until RX buffer is ready while (! (UCB2IFG & UCRXIFG)) ; return UCB2RXBUF;
}

When I run my code in debug with break points on the first and the second "while" of the "transfert" function, I can access the SPI controller registers. The configuration matches my settings:

UCB2CTLW0 = 0x6900
UCB2RW = 0x0078
UCB2STATW = 0x0001 (I can't find info about this register's bits..)
UCB2IE = 0x0003

After the first data is sent to UCB2TXBUF the UCB2IFG registers' bit TXIFG does not get set. The RXIFG bit stays to 0 and this makes the "transfert" function to block at the second while.. As I wrote at the start of the post, I don't see any clock on P3.5 after the UCB2TXBUF is write (this might be the problem, but what's the cause.. ?)

I tried different configurations, I read the datasheet and the technical manual several times (SPI and Clock parts) but nothing helped me to find out what I'm doing wrong.. 

Any help/tips on this would be great (: I can post more code if you need so

I thank you for having read the ticket and your future replies (:

Jean-Baptiste

  • Hello,

    If you would like to output ACLK/SMCLK directly, you have to change the associated GPIO functions to do this. I believe you mean the SPI CLCK for P3.5 though. Please check the TRM again for valid register values for the clock source for eUSCIA/B. Only ACLK and SMCLK can be used. The code line, 

    UCB2CTLW0 |= UCSSEL_0;

    is your issue here for a value of 0x00 is not a valid clock selection. To avoid confusion, I recommend using the predefined values :

    UCSSEL__ACLK
    
    or
    
    UCSSEL__SMCLK

  • Hello,

    Thank you for your help, it works now!

**Attention** This is a public forum