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.

Tiva - multiple interrupt firing and ssi (spi comm) issue.

Other Parts Discussed in Thread: MSP430G2553, TM4C123GH6PZ

hi ,

i am trying to communicate between a Tiva TM4c123g (master )and an msp430G2553 (slave) both launchpads using spi communication.

i am enabling 2 interrupts one for spi (ssi ) and the other for timerA.

i have two issues here:

1. the spi does not seem to work as expected i am not getting the intended data at the master on receive . the msp430 slave has a echo code only.

i have changed the array size from 1 to 3 but still dont see the correct data ? could you suggest changes in the code to enable the same. 

also please let me know if it is possible to debug by putting breakpoint while using spi.?

2. once the interrupts are fired. it enters the timer isr and then the ssi function . After which it remained or toggles between the two isrs as and when fired and does not come back to main ( in this case the while (1) or any other statement).  Only disabling the interrupt in the isr  seems to bring it back to main which is not ideally required. 

could you help me with the same ?

i have attached the main code .

#include <stdint.h>
#include "inc/tm4c123gh6pz.h"
int x,y;

//*****************************************************************************
//
// Number of bytes to send and receive.
//
//*****************************************************************************
#define NUM_SSI_DATA 3

uint32_t pui32DataTx[NUM_SSI_DATA];
uint32_t pui32DataRx[NUM_SSI_DATA];
uint32_t ui32Index;

void main(void)
{

SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_20MHZ);
//
// The SSI0 peripheral must be enabled for use.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);



GPIOPinConfigure(GPIO_PA2_SSI0CLK);
// GPIOPinConfigure(GPIO_PA3_SSI0FSS);
GPIOPinConfigure(GPIO_PA4_SSI0RX);
GPIOPinConfigure(GPIO_PA5_SSI0TX);


// The pins are assigned as follows:
// PA5 - SSI0Tx
// PA4 - SSI0Rx
// PA3 - SSI0Fss
// PA2 - SSI0CLK

GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_2); // | GPIO_PIN_3);

TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
TimerLoadSet(TIMER0_BASE, TIMER_A, 12500);

//////////////// TIMER Initialization ///////////////////////////

IntEnable(INT_TIMER0A);
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
TimerEnable(TIMER0_BASE, TIMER_A);

//
SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 1000000, 8);

// Enable the SSI0 module.
SSIEnable(SSI0_BASE);

SSIIntEnable(SSI0_BASE,SSI_TXFF| SSI_RXFF);

GPIO_PORTA_DIR_R = 0x08;
GPIO_PORTA_DEN_R = 0x08;

GPIO_PORTA_DATA_R &= ~(0x08);
GPIO_PORTA_DATA_R |= 0x08;


while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx[0]))
{
}

//
// Initialize the data to send.
//
pui32DataTx[0] = 's';
pui32DataTx[1] = 'p';
pui32DataTx[2] = 'i';

IntEnable(INT_SSI0);

IntMasterEnable();


while(1);


}


void SSI0IntHandler(void)
{ x++;

SSIIntClear(SSI0_BASE,SSI_TXFF| SSI_RXFF);
//
// Send 3 bytes of data.
//
for(ui32Index = 0; ui32Index < NUM_SSI_DATA; ui32Index++)
{

SSIDataPut(SSI0_BASE, pui32DataTx[ui32Index]);
}


while(SSIBusy(SSI0_BASE))
{
}

//
// Receive 3 bytes of data.
//
for(ui32Index = 0; ui32Index < NUM_SSI_DATA; ui32Index++)
{

SSIDataGet(SSI0_BASE, &pui32DataRx[ui32Index]);

pui32DataRx[ui32Index] &= 0x00FF;
}


}


void Timer0IntHandler(void)
{
y++;
// Clear the timer interrupt.
//
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
}

thanks,

Meghana.

  • Hello Meghana,

    I have noticed that you are using "SYSCTL_XTAL_20MHZ" for the crystal. But the launchpad board has a 16MHz crystal. You might want to change that to "SYSCTL_XTAL_16MHZ". 

    In the "SSI0IntHandler()", it is better if you can read the cause of the interrupt (using SSIIntStatus()) into a variable and only clear the ones that caused the interrupt. Then check for the cause of the interrupt and handle accordingly. Example if the interrupt has been caused by "SSI_RXFF" read the RX FIFO alone. This will also help in debug because now you can have a counter that can be updated in the interrupt handler and monitored in the main loop.

    I am not sure why it never returns to the main loop after the interrupts are fired, but the current implementation blocks the SSI0's ISR which can be avoided by following the above mentioned method. To narrow down the problem you can use polling to send and receive packets over SSI instead of using interrupts. This implementation in demonstrated in the TivaWare under "<install_directory>/ examples/peripherals/ssi/spi_master".

    As far as using breakpoints with SSI is concerned, I can think of no reason why it should be any different when compared to, say, using with UART.

    Hope this helps!

    Regards,
    Sai