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.
Hello,
I have trouble receiving data from my FRAM Board. My FG4618 should send 'a' over the SPI bus while my FR5739 echos the data back. If my FG4618 receives 'a' it should power up the LED. For some reason I am able so send the 'a' over SPI but does not receive it back. Here the Code of both of them:
FG4618:
#include <msp430.h> unsigned char MST_Data, SLV_Data; int main(void) { volatile unsigned int i; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer FLL_CTL0 |= XCAP14PF; // Configure load caps P2DIR = 0xFF; // Wait for xtal to stabilize do { IFG1 &= ~OFIFG; // Clear OSCFault flag for (i = 0x47FF; i > 0; i--) ; // Time for flag to set } while ((IFG1 & OFIFG)); // OSCFault flag still set? for (i = 2100; i > 0; i--) ; // Now with stable ACLK, wait for // DCO to stabilize. P5OUT = 0x04; // P5 setup for LED and slave reset P5DIR |= 0x06; // P7SEL |= 0x0E; // P7.3,2,1 option select UCA0CTL0 |= UCMST + UCSYNC + UCCKPL + UCMSB; //3-pin, 8-bit SPI master UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 0x02; // /2 UCA0BR1 = 0; // UCA0MCTL = 0; // No modulation UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt P5OUT &= ~0x04; // Now with SPI signals initialized, P5OUT |= 0x04; // reset slave P5OUT &= ~0x02; while (!(IFG2 & UCA0TXIFG)); // USART1 TX buffer ready? UCA0TXBUF = 'a'; // Transmit character while (1) { // P2OUT ^= 0x02; // Toggle P2.0 using exclusive-OR // // i = 10000; // SW Delay // do // i--; // while (i != 0); __delay_cycles(1000000); } // __bis_SR_register(LPM0_bits + GIE); __bis_SR_register(GIE); // CPU off, enable interrupts } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCIAB0RX_VECTOR __interrupt void USCIA0RX_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCIAB0RX_VECTOR))) USCIA0RX_ISR (void) #else #error Compiler not supported! #endif { volatile unsigned int i; while (!(IFG2 & UCA0TXIFG)) // USART1 TX buffer ready? ; if (UCA0RXBUF == 'a') // Test for correct character RX'd P2OUT |= 0x02; // If correct, light LED else P2OUT &= ~0x02; // If incorrect, clear LED // MST_Data++; // Increment data // SLV_Data++; // UCA0TXBUF = MST_Data; // Send next value for (i = 100; i > 0; i--) ; // Add time between transmissions to } // make sure slave can keep up
For FR5739:
#include <msp430.h> typedef enum { NO_LED, LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8 } ledEnum; void turnLedOn(char ledNum); void turnLedOff(char ledNum); int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P3DIR = 0xFF; // Configure XT1 PJSEL0 |= BIT4 + BIT5; CSCTL0_H = 0xA5; CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_0 + SELS_3 + SELM_3; // set ACLK = XT1; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_3 + DIVM_3; // set all dividers CSCTL4 |= XT1DRIVE_0; CSCTL4 &= ~XT1OFF; do { CSCTL5 &= ~XT1OFFG; // Clear XT1 fault flag SFRIFG1 &= ~OFIFG; } while (SFRIFG1 & OFIFG); // Test oscillator fault flag // Configure SPI pins P1SEL1 |= BIT5; P2SEL1 |= BIT0 + BIT1; UCA0CTLW0 |= UCSWRST; // **Put state machine in reset** UCA0CTLW0 |= UCSYNC + UCCKPL + UCMSB; // 3-pin, 8-bit SPI slave // Clock polarity high, MSB UCA0CTLW0 |= UCSSEL_2; // ACLK UCA0BR0 = 0x02; // /2 UCA0BR1 = 0; // UCA0MCTLW = 0; // No modulation UCA0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt turnLedOff(6); turnLedOff(7); turnLedOff(8); // __bis_SR_register(LPM0_bits + GIE); __bis_SR_register(GIE); while(1) { turnLedOn(5); __delay_cycles(1000000); turnLedOff(5); __delay_cycles(1000000); } // Enter LPM0, enable interrupts } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void) #else #error Compiler not supported! #endif { while (!(UCA0IFG & UCTXIFG)) ; // USCI_A0 TX buffer ready? if(UCA0RXBUF=='a') { UCA0TXBUF = UCA0RXBUF; // Echo received data P3OUT ^= (BIT6); } }
The shematic is:
MSP430FG4618:
P7.1|-> Data Out (UCA0SIMO)
P7.2|<- Data In (UCA0SOMI)
P7.3|-> Serial Clock Out (UCA0CLK)
MSP430FR5739:
P4.3|<- Data In (SIMO1)
P4.4|-> Data Out (SOMI1)
P4.5|<- Serial Clock In (UCLK1)
I would appreciate any help. Either the FRAM board does not send anything back. Or the MSP430FG4618 does not receive anything...
regards
Yes I have. As you can see, I am toggeling some Leds in order to verify the communication. After I start the MSP430FR5739 code, LED5 starts to blink as programmed. The second I start the MSP430FG4618 (master) code, LED7 toggles to HIGH and stays there. For some reason one send cycle is transmitted successfully but after that LED7 never toggles again. My master LED never lights up...
yes it is connected to P3.6. sorry I forgot to append my functions:
void turnLedOn(char ledNum) { switch (ledNum) { case LED1: PJOUT |= (BIT0); break; case LED2: PJOUT |= (BIT1); break; case LED3: PJOUT |= (BIT2); break; case LED4: PJOUT |= (BIT3); break; case LED5: P3OUT |= (BIT4); break; case LED6: P3OUT |= (BIT5); break; case LED7: P3OUT |= (BIT6); break; case LED8: P3OUT |= (BIT7); break; } }
What do you mean by "when i first send a byte the receiver sends the data in the txbuffer only in the next communcation cycle"? And why is there a 'b' now? You were talking about 'a' before.
By the way...
UCA0CTLW0 |= UCSSEL_2; // ACLK
does not match since UCSSEL_2 is SMCLK, but the MSP430FR5739 is the slave, so any clock settings are don't care...at least for the receiving site. And this could be your problem - how do you want to echo the data back? Is your slave clocked by the master for echoing back the data as well? Or shall the slave clock the data out by itself? Wouldn't it need to be a master in that case? But from this "when i first send a byte the receiver sends the data in the txbuffer only in the next communcation cycle" I would guess you mean exactly that, right? You need to clock in another 8 bits to get data out of the slave.
Dennis
You are right I am sorry. for better reading and understanding I post my modified code once again:
Master:
#include <msp430.h> unsigned char MST_Data, SLV_Data; char spi_transmit(char data); int main(void) { volatile unsigned int i; char wert; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer FLL_CTL0 |= XCAP14PF; // Configure load caps P2DIR = 0xFF; // Wait for xtal to stabilize do { IFG1 &= ~OFIFG; // Clear OSCFault flag for (i = 0x47FF; i > 0; i--) ; // Time for flag to set } while ((IFG1 & OFIFG)); // OSCFault flag still set? for (i = 2100; i > 0; i--) ; // Now with stable ACLK, wait for // DCO to stabilize. P5OUT = 0x04; // P5 setup for LED and slave reset P5DIR |= 0x06; // P7SEL |= 0x0E; // P7.3,2,1 option select UCA0CTL0 |= UCMST + UCSYNC + UCCKPL + UCMSB; //3-pin, 8-bit SPI master UCA0CTL1 |= UCSWRST; // **Put state machine in reset** UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 0x02; // /2 UCA0BR1 = 0; // UCA0MCTL = 0; // No modulation UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt P5OUT &= ~0x04; // Now with SPI signals initialized, P5OUT |= 0x04; // reset slave P5OUT &= ~0x02; P2OUT = 0x00; // __bis_SR_register(LPM0_bits + GIE); // __bis_SR_register(GIE); // CPU off, enable interrupts while (1) { if (spi_transmit('a') == 'b') { P2OUT |= 0x02; // If correct, light LED } // __delay_cycles(1000000); // if (spi_transmit('c') == 'd') // { // P2OUT &= ~0x02; // If correct, light LED // } // __delay_cycles(1000000); // if (spi_transmit('e') == 'f') // { // P2OUT |= 0x02; // If correct, light LED // } P5OUT ^= 0x02; __delay_cycles(1000000); } } char spi_transmit(char data) { UCA0TXBUF = data; while (!(IFG2 & UCA0RXIFG));// wait for transfer to complete IFG2 &= ~UCA0RXIFG; // clear the rx flag return (UCA0RXBUF); }
Slave:
#include <msp430.h> typedef enum { NO_LED, LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8 } ledEnum; void turnLedOn(char ledNum); void turnLedOff(char ledNum); volatile int flag = 0; volatile char wert, test, receive; int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P3DIR = 0xFF; // Configure XT1 PJSEL0 |= BIT4 + BIT5; CSCTL0_H = 0xA5; CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_0 + SELS_3 + SELM_3; // set ACLK = XT1; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_3 + DIVM_3; // set all dividers CSCTL4 |= XT1DRIVE_0; CSCTL4 &= ~XT1OFF; do { CSCTL5 &= ~XT1OFFG; // Clear XT1 fault flag SFRIFG1 &= ~OFIFG; } while (SFRIFG1 & OFIFG); // Test oscillator fault flag // Configure SPI pins P1SEL1 |= BIT5; P2SEL1 |= BIT0 + BIT1; UCA0CTLW0 |= UCSWRST; // **Put state machine in reset** UCA0CTLW0 |= UCSYNC + UCCKPL + UCMSB; // 3-pin, 8-bit SPI slave // Clock polarity high, MSB UCA0CTLW0 |= UCSSEL_2; // ACLK UCA0BR0 = 0x02; // /2 UCA0BR1 = 0; // UCA0MCTLW = 0; // No modulation UCA0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt turnLedOff(6); turnLedOff(7); turnLedOff(8); // __bis_SR_register(LPM0_bits + GIE); __bis_SR_register(GIE); while (1) { wert = test; turnLedOn(5); __delay_cycles(1000000); turnLedOff(5); __delay_cycles(1000000); if(flag==1) { // turnLedOn(6); P3OUT ^= (BIT5); // while (!(UCA0IFG & UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = 'b'; } else if(flag==2) { turnLedOn(7); while (!(UCA0IFG & UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = 'd'; } else if(flag==3) { turnLedOn(8); while (!(UCA0IFG & UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = 'f'; } } } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void) #else #error Compiler not supported! #endif { receive=UCA0RXBUF; if (receive == 'a') { flag = 1; } if (receive == 'c') { flag = 2; } if (receive == 'e') { flag = 3; } }
Hope that clears my mistake.
Hey Dennis,
thank you for your time and post. The line number you quoted is a inspiration by the template of TI’ itself. The MSP430FR57xx_uscia0_spi_10.c for the MSP430FR5739 does exactly the same as I am trying:
// MSP430F54x Demo - USCI_A0, SPI 3-Wire Slave Data Echo // // Description: SPI slave talks to SPI master using 3-wire mode. Data received // from master is echoed back. // ACLK = 32.768kHz, MCLK = SMCLK = DCO ~ 1MHz // Note: Ensure slave is powered up before master to prevent delays due to // slave init. // // // MSP430FR5739 // ----------------- // /|\ | | // | | | // -+->| | // | | // | P2.0|-> Data Out (UCA0SIMO) // | | // | P2.1|<- Data In (UCA0SOMI) // | | // | P1.5|-> Serial Clock Out (UCA0CLK) // // // P. Thanigai // Texas Instruments Inc. // August 2010 // Built with CCS V4 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include <msp430.h> int main(void) { WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer // Configure XT1 PJSEL0 |= BIT4+BIT5; CSCTL0_H = 0xA5; CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_0 + SELS_3 + SELM_3; // set ACLK = XT1; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_3 + DIVM_3; // set all dividers CSCTL4 |= XT1DRIVE_0; CSCTL4 &= ~XT1OFF; do { CSCTL5 &= ~XT1OFFG; // Clear XT1 fault flag SFRIFG1 &= ~OFIFG; }while (SFRIFG1&OFIFG); // Test oscillator fault flag // Configure SPI pins P1SEL1 |= BIT5; P2SEL1 |= BIT0 + BIT1; UCA0CTLW0 |= UCSWRST; // **Put state machine in reset** UCA0CTLW0 |= UCSYNC+UCCKPL+UCMSB; // 3-pin, 8-bit SPI slave // Clock polarity high, MSB UCA0CTLW0 |= UCSSEL_2; // ACLK UCA0BR0 = 0x02; // /2 UCA0BR1 = 0; // UCA0MCTLW = 0; // No modulation UCA0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void) #else #error Compiler not supported! #endif { while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = UCA0RXBUF; // Echo received data }
>>
Is your slave clocked by the master for echoing back the data as well?
<<
According to my pin description, yes:
MSP430FG4618:
P7.1|-> Data Out (UCA0SIMO)
P7.2|<- Data In (UCA0SOMI)
P7.3|-> Serial Clock Out (UCA0CLK)
MSP430FR5739:
P4.3|<- Data In (SIMO1)
P4.4|-> Data Out (SOMI1)
P4.5|<- Serial Clock In (UCLK1)
I wired these connections...
>>
You need to clock in another 8 bits to get data out of the slave.
<<
Yes I am sending continuously ‘a’ to the slave but never receives ‘b’. Even if the first received data from the slave is wrong, at least since the second cycle I should receive ‘b’ the slave wrote into the transmit buffer from my first send request.
Hello,
I have just answered byt my post is suddenly removed. Here agein:
The line you quoted is inspired by the TI’s code itself. In the MSP430FR57xx_uscia0_spi_10.c Ti configured the MSP430FR5739 as a slave as well as I did:
/* --COPYRIGHT--,BSD_EX * Copyright (c) 2012, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************* * * MSP430 CODE EXAMPLE DISCLAIMER * * MSP430 code examples are self-contained low-level programs that typically * demonstrate a single peripheral function or device feature in a highly * concise manner. For this the code may rely on the device's power-on default * register values and settings such as the clock configuration and care must * be taken when combining code from several examples to avoid potential side * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware * for an API functional library-approach to peripheral configuration. * * --/COPYRIGHT--*/ //****************************************************************************** // MSP430F54x Demo - USCI_A0, SPI 3-Wire Slave Data Echo // // Description: SPI slave talks to SPI master using 3-wire mode. Data received // from master is echoed back. // ACLK = 32.768kHz, MCLK = SMCLK = DCO ~ 1MHz // Note: Ensure slave is powered up before master to prevent delays due to // slave init. // // // MSP430FR5739 // ----------------- // /|\ | | // | | | // -+->| | // | | // | P2.0|-> Data Out (UCA0SIMO) // | | // | P2.1|<- Data In (UCA0SOMI) // | | // | P1.5|-> Serial Clock Out (UCA0CLK) // // // P. Thanigai // Texas Instruments Inc. // August 2010 // Built with CCS V4 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include <msp430.h> int main(void) { WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer // Configure XT1 PJSEL0 |= BIT4+BIT5; CSCTL0_H = 0xA5; CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_0 + SELS_3 + SELM_3; // set ACLK = XT1; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_3 + DIVM_3; // set all dividers CSCTL4 |= XT1DRIVE_0; CSCTL4 &= ~XT1OFF; do { CSCTL5 &= ~XT1OFFG; // Clear XT1 fault flag SFRIFG1 &= ~OFIFG; }while (SFRIFG1&OFIFG); // Test oscillator fault flag // Configure SPI pins P1SEL1 |= BIT5; P2SEL1 |= BIT0 + BIT1; UCA0CTLW0 |= UCSWRST; // **Put state machine in reset** UCA0CTLW0 |= UCSYNC+UCCKPL+UCMSB; // 3-pin, 8-bit SPI slave // Clock polarity high, MSB UCA0CTLW0 |= UCSSEL_2; // ACLK UCA0BR0 = 0x02; // /2 UCA0BR1 = 0; // UCA0MCTLW = 0; // No modulation UCA0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void) #else #error Compiler not supported! #endif { while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = UCA0RXBUF; // Echo received data }
>>
You need to clock in another 8 bits to get data out of the slave.
<<
Yes, I am already sending continuously ‘a’ to the slave. Even if the first byte received from the slave is not ‘b’ as expected at least after the second cycle I should have received ‘b’ the slave put in transmit buffer from the first cycle…
**Attention** This is a public forum