I am using TI-RTOS (SYS/BIOS) in 2 MSP430F5529 and trying to have the F5529s to talk to each other through SPI.
Master basically does this:
while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready? if (UCA0RXBUF==SLV_Data) // Test for correct character RX'd P1OUT |= 0x01; // If correct, light LED else P1OUT &= ~0x01; // 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 process information
Slave basically does this:
while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = UCA0RXBUF;
The master is suppose to tx a number, and the slave is suppose to tx the number - 1. This works without RTOS. However, with RTOS, the slave is tx-ing the number - 2.
Seems like the slave is delayed. Could anyone help on this?
- RW
Code for the master and slave, main.c and app.cfg:
/* * ======== main.c ======== */ #include <xdc/std.h> #include <ti/sysbios/BIOS.h> #include <xdc/cfg/global.h> #include <xdc/runtime/System.h> #include <xdc/runtime/Log.h> #include <msp430.h> #include <driverlib.h> #define SPI_CLK_HZ 320000 void start_SPI( void ); //----------------------------------------- // Globals //----------------------------------------- unsigned char MST_Data,SLV_Data; unsigned char temp; /* * ======== main ======== */ Int main(){ volatile unsigned int i; WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer UCSCTL1 = DCORSEL_5; UCSCTL2 = FLLD_1 + FLLN8 + FLLN7 + FLLN6 + FLLN4 + FLLN3 + FLLN0; UCSCTL3 = SELREF_2 + FLLREFDIV_0; UCSCTL4 = SELA_2 + SELS_4 + SELM_4; UCSCTL5 = DIVPA_0 + DIVA_0 + DIVS_0 + DIVM_0; UCSCTL6 = 0xC1CD; UCSCTL7 = 0x0400; UCSCTL8 = 0x0707; P1OUT |= 0x02; // Set P1.0 for LED // Set P1.1 for slave reset P1DIR |= 0x03; // Set P1.0-2 to output direction P3SEL |= BIT3+BIT4; // P3.3,4 option select P2SEL |= BIT7; // P2.7 option select UCA0CTL1 |= UCSWRST; // **Put state machine in reset** USCI_A_SPI_initMasterParam param = { 0 }; param.selectClockSource = USCI_A_SPI_CLOCKSOURCE_SMCLK; param.clockSourceFrequency = UCS_getSMCLK(); param.desiredSpiClock = SPI_CLK_HZ; param.msbFirst = USCI_A_SPI_MSB_FIRST; param.clockPhase = USCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT; param.clockPolarity = USCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW; USCI_A_SPI_initMaster( USCI_A0_BASE, ¶m ); UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt P1OUT &= ~0x02; // Now with SPI signals initialized, P1OUT |= 0x02; // reset slave for(i=50;i>0;i--); // Wait for slave to initialize MST_Data = 0x01; // Initialize data values SLV_Data = 0x00; // while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = MST_Data; // Transmit first character __bis_SR_register(GIE); // CPU off, enable interrupts System_printf( "Start BIOS_start\n" ); System_flush(); BIOS_start(); /* does not return */ return(0); } void start_SPI( void ){ volatile unsigned int i; while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready? if (UCA0RXBUF==SLV_Data) // Test for correct character RX'd P1OUT |= 0x01; // If correct, light LED else P1OUT &= ~0x01; // 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 process information }
/* * ======== main.c ======== */ #include <xdc/std.h> #include <ti/sysbios/BIOS.h> #include <xdc/cfg/global.h> #include <xdc/runtime/System.h> #include <xdc/runtime/Log.h> #include <msp430.h> #include <driverlib.h> //----------------------------------------- // Globals //----------------------------------------- void start_SPI( void ); /* * ======== main ======== */ Int main(){ WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer UCSCTL1 = DCORSEL_5; UCSCTL2 = FLLD_1 + FLLN8 + FLLN7 + FLLN6 + FLLN5 + FLLN4 + FLLN3 + FLLN0; UCSCTL3 = SELREF_2 + FLLREFDIV_0; UCSCTL4 = SELA_2 + SELS_4 + SELM_4; UCSCTL5 = DIVPA_0 + DIVA_0 + DIVS_0 + DIVM_0; UCSCTL6 = 0xC1CD; UCSCTL7 = 0x0400; UCSCTL8 = 0x0707; //P2DIR |= BIT2; // Define P1.0 and P1.4 as outputs //P2SEL |= BIT2; // Connect ACLK to P1.0 and SMCLK to P1.4, // and set all other bits for digital I/O. // while(!(P2IN&0x80)); // If clock sig from mstr stays low, // it is not yet in SPI mode P3SEL |= BIT3+BIT4; // P3.3,4 option select P2SEL |= BIT7; // P2.7 option select USCI_A_SPI_disable( USCI_A0_BASE ); // **Put state machine in reset** USCI_A_SPI_initSlave( USCI_A0_BASE, USCI_A_SPI_MSB_FIRST, USCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT, USCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW ); USCI_A_SPI_enable( USCI_A0_BASE ); // **Initialize USCI state machine** USCI_A_SPI_enableInterrupt( USCI_A0_BASE, UCRXIE ); // Enable USCI_A0 RX interrupt __bis_SR_register( GIE ); // Enter LPM4, enable interrupts System_printf( "Start BIOS_start()\n" ); System_flush(); BIOS_start(); /* does not return */ return( 0 ); } void start_SPI( void ){ while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = UCA0RXBUF; }