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.
Hi,
I am having some trouble with the eUSCI of the MSP430FR2100 in SPI mode.
The code below is a simplified version of the example "msp430fr211x_eusci_spi_standard_slave.c" with added support for the "MSP430FR4133 LaunchPad Development Kit".
(MSP430Ware_3_80_04_05/examples/devices/MSP430FR2xx_4xx/MSP430FR21xx_MSP430FR2000_Code_Examples/C/msp430fr211x_eusci_spi_standard_slave.c)
As seen in the interrupt routine each received char is simply written to the transmit register unless the value is 0xAA in which case 0x00 is written.
Placing an interrupt at line 136 "if (uca0_rx_val == 0xAA)" and running the code on the MSP430FR4133 works as expected.
However when the code is run on the MSP430FR2100 the break-point in the interrupt routine is only hit for every 8th char received. Also the transmitted char is shifted as seen below:
root@host:~# spidev_test -D /dev/spidev0.0 -H -O -s 1000 -v -p "\x10"
spi mode: 0x3
bits per word: 8
max speed: 1000 Hz (1 KHz)
TX | 10 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -H -O -s 1000 -v -p "\x10"
spi mode: 0x3
bits per word: 8
max speed: 1000 Hz (1 KHz)
TX | 10 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -H -O -s 1000 -v -p "\x10"
spi mode: 0x3
bits per word: 8
max speed: 1000 Hz (1 KHz)
TX | 10 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 04 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -H -O -s 1000 -v -p "\x10"
spi mode: 0x3
bits per word: 8
max speed: 1000 Hz (1 KHz)
TX | 10 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 08 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -H -O -s 1000 -v -p "\x10"
spi mode: 0x3
bits per word: 8
max speed: 1000 Hz (1 KHz)
TX | 10 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 10 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
Does anybody have an idea about what is going on here and how to solve this issue.
Best regards,
Anders
//****************************************************************************** // MSP430FR211x Demo - eUSCI_A0, SPI 4-Wire Slave multiple byte RX/TX // // Description: SPI master communicates to SPI slave sending and receiving // 3 different messages of different length. SPI slave will enter LPM0 // while waiting for the messages to be sent/receiving using SPI interrupt. // ACLK = NA, MCLK = SMCLK = DCO 16MHz. // // // MSP430FR2111 // ----------------- // /|\ | RST |<- Master's GPIO (To reset slave) // | | | // ---|RST P1.7|<- Data In (UCA0SIMO) // | | // | P1.6|-> Data Out (UCA0SOMI) // | | // | P1.5|<- Serial Clock In (UCA0CLK) // | | // | P1.4|<- Master's GPIO (UCA0STE) // // Nima Eskandari and Ryan Meredith // Texas Instruments Inc. // February 2018 // Built with CCS V7.3 //****************************************************************************** #include <msp430.h> #include <stdint.h> #include <stdbool.h> //****************************************************************************** // Device Initialization ******************************************************* //****************************************************************************** void initSPI() { #ifdef __MSP430FR4133__ UCB0CTLW0 = UCSWRST; // **Put state machine in reset** UCB0CTLW0 |= UCCKPL | UCMSB | UCSYNC | UCMODE_2; // 4-pin, 8-bit SPI Slave UCB0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine** UCB0IE |= UCRXIE; // Enable USCI0 RX interrupt #else //Clock Polarity: The inactive state is high //MSB First, 8-bit, Master, 4-pin mode, Synchronous UCA0CTLW0 = UCSWRST; // **Put state machine in reset** UCA0CTLW0 |= UCCKPL | UCMSB | UCSYNC | UCMODE_2; // 4-pin, 8-bit SPI Slave UCA0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE; // Enable USCI0 RX interrupt #endif } void initGPIO() { // Configure GPIO #ifdef __MSP430FR4133__ P5SEL0 |= BIT0 | BIT1 | BIT2 | BIT3; #else P1SEL0 |= BIT4 | BIT5 | BIT6 | BIT7; // Configure SPI pins #endif // P1SEL1 = 0x00; // Disable the GPIO power-on default high-impedance mode to activate // previously configured port settings PM5CTL0 &= ~LOCKLPM5; } void initClockTo16MHz() { // Configure one FRAM waitstate as required by the device datasheet for MCLK // operation beyond 8MHz _before_ configuring the clock system. FRCTL0 = FRCTLPW | NWAITS_1; __bis_SR_register(SCG0); // disable FLL CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source CSCTL0 = 0; // clear DCO and MOD registers CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first CSCTL1 |= DCORSEL_5; // Set DCO = 16MHz CSCTL2 = FLLD_0 + 487; // set to fDCOCLKDIV = (FLLN + 1)*(fFLLREFCLK/n) // = (487 + 1)*(32.768 kHz/1) // = 16 MHz __delay_cycles(3); __bic_SR_register(SCG0); // enable FLL while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // FLL locked } //****************************************************************************** // Main ************************************************************************ // Enters LPM0 and waits for SPI interrupts. The data sent from the master is * // then interpreted and the device will respond accordingly * //****************************************************************************** int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer initClockTo16MHz(); initGPIO(); initSPI(); __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts __no_operation(); return 0; } //****************************************************************************** // SPI Interrupt *************************************************************** //****************************************************************************** #ifdef __MSP430FR4133__ #pragma vector=USCI_B0_VECTOR __interrupt void USCI_B0_ISR(void) #else #pragma vector=USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) #endif { uint8_t uca0_rx_val = 0; #ifdef __MSP430FR4133__ switch(__even_in_range(UCB0IV, USCI_SPI_UCTXIFG)) #else switch(__even_in_range(UCA0IV, USCI_SPI_UCTXIFG)) #endif { case USCI_NONE: break; case USCI_SPI_UCRXIFG: #ifdef __MSP430FR4133__ uca0_rx_val = UCB0RXBUF; UCB0IFG &= ~UCRXIFG; #else uca0_rx_val = UCA0RXBUF; UCA0IFG &= ~UCRXIFG; #endif if (uca0_rx_val == 0xAA) uca0_rx_val = 0x00; #ifdef __MSP430FR4133__ while (!(UCB0IFG & UCTXIFG)); // USCI_A0 TX buffer ready? UCB0TXBUF = uca0_rx_val; #else while (!(UCA0IFG & UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = uca0_rx_val; #endif break; case USCI_SPI_UCTXIFG: break; default: break; } }
Hi again,
Tried changing the SPI mode from 0x3 to 0x0 (by replacing UCCKPL with UCCKPH) and that solves the byte shift issue.
Still only get an interrupt for every 8th char though. I see the following behavior.
- First char triggers the RX interrupt
- The next 7 chars does not trigger the RX interrupt
- 8th char triggers the RX interrupt
and so on as seen below. The code works perfectly on the MSP430FR4133 as before.
root@host:~# spidev_test -D /dev/spidev0.0 -s 40000 -p "\x01" -v
spi mode: 0x0
bits per word: 8
max speed: 40000 Hz (40 KHz)
TX | 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -s 40000 -p "\x02" -v
spi mode: 0x0
bits per word: 8
max speed: 40000 Hz (40 KHz)
TX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -s 40000 -p "\x02" -v
spi mode: 0x0
bits per word: 8
max speed: 40000 Hz (40 KHz)
TX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -s 40000 -p "\x02" -v
spi mode: 0x0
bits per word: 8
max speed: 40000 Hz (40 KHz)
TX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -s 40000 -p "\x02" -v
spi mode: 0x0
bits per word: 8
max speed: 40000 Hz (40 KHz)
TX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -s 40000 -p "\x02" -v
spi mode: 0x0
bits per word: 8
max speed: 40000 Hz (40 KHz)
TX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -s 40000 -p "\x02" -v
spi mode: 0x0
bits per word: 8
max speed: 40000 Hz (40 KHz)
TX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -s 40000 -p "\x02" -v
spi mode: 0x0
bits per word: 8
max speed: 40000 Hz (40 KHz)
TX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -s 40000 -p "\x02" -v
spi mode: 0x0
bits per word: 8
max speed: 40000 Hz (40 KHz)
TX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~# spidev_test -D /dev/spidev0.0 -s 40000 -p "\x02" -v
spi mode: 0x0
bits per word: 8
max speed: 40000 Hz (40 KHz)
TX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
RX | 02 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ | .
root@host:~#
Here is the Saleae logic analyzer output from the MSP430FR4133 setup that is using an RPI and spidev_test as the master. Notice that on the MSP430FR2100 test setup above there is 9 clock periods and only 8 on the MSP430FR4133 setup. Could this be the cause of only getting an USCI_SPI_UCRXIFG interrupt for every 8th char received?
Tried to connect the MSP430FR4133 MCU to the MSP430FR2100 SPI master using the measuring wires soldered on the prototype board. Using this setup I get an interrupt for every char. Therefore the missing interrupt issue must be caused by missing configuration of the MSP430FR2100. However the sample code does not provide any clue about what is missing. It seems to have been only tested on the MSP-EXP430FR4133 evaluation board.
Have also tried using the SPI init function from the example http://www.ti.com/lit/pdf/slaa807
void initSPI(void) { P1SEL0 |= BIT4 | BIT5 | BIT6 | BIT7; // set 4-SPI pin as second function UCA0CTLW0 |= UCSWRST; // **Put state machine in reset** // 4-pin, 8-bit SPI slave UCA0CTLW0 |= UCSYNC|UCCKPH|UCMSB|UCMODE_2|UCSTEM|UCSSEL__SMCLK; // SPI mode is selected when the UCSYNC bit is set // Clock polarity inactive state high // MSB first, 8-bit character length // 4-pin SPI with STE active low // STE pin generates the enable signal for 4-wire slave // eUSCI clock source select SMCLK UCA0BR0 = 0x01; // Bit clock prescaler setting: BRCLK = SMCLK/1 UCA0MCTLW = 0; // clear MCTLW when using SPI mode for eUSCI_A UCA0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt }
However this makes no difference. Interrupts are still misbehaving.
Also tried running the ASM example "MSP430Ware_3_80_04_05/examples/devices/MSP430FR2xx_4xx/MSP430FR413x_MSP430FR203x_Code_Examples/Assembly_CCS/msp430fr413x_uscia0_spi_12.asm" with the same result. Had to modify it slightly to match the HW of cause as shown below:
--- msp430fr413x_uscia0_spi_12.asm 2018-04-30 19:30:00.000000000 +0200 +++ workspace_v8/msp430_asm_test/msp430fr413x_uscia0_spi_12.asm 2018-11-02 12:50:08.079405737 +0100 @@ -86,11 +86,12 @@ RESET mov.w #__STACK_END,SP ; Initialize stack pointer mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT - bis.b #BIT0+BIT1+BIT2,&P1SEL0 + bis.b #BIT4+BIT5+BIT6+BIT7,&P1SEL0 bis.w #UCSWRST,&UCA0CTLW0 ; **Put state machine in reset** - bis.w #UCSYNC+UCCKPL+UCMSB,&UCA0CTLW0 ; 3-pin, 8-bit SPI master + bis.w #UCCKPH+UCMSB+UCSYNC+UCMODE_2,&UCA0CTLW0 ; 4-pin, 8-bit SPI master ; Clock polarity high, MSB - bis.w #UCSSEL__MODCLK,&UCA0CTLW0 ; MODCLK +; bis.w #UCSSEL__MODCLK,&UCA0CTLW0 ; ACLK + bis.w #UCSSEL_2,&UCA0CTLW0 ; ACLK mov.b #0x01,&UCA0BR0 ; /2 clr.b &UCA0BR1 clr.w &UCA0MCTLW ; No modulation
**Attention** This is a public forum