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.

LM4F120: SPI (SSI) - interrupt receiving and transmitting

Hello all,

I'm new in LM4F family

I want to receive data from SPI using interrupt. Suppose there is any slave module that transmit to us packets of data. The size of packets are different e.g. 5-20 bytes long.

It's not a real problem, I'm just interesting how could I create something like this and I want to ask you for some things.

1. System clock:

// Setup the system clock to run at 50 Mhz from PLL with crystal reference       
SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ| SYSCTL_OSC_MAIN);

2. SPI configuration:

        // SSI0 enable
        SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);

        // GPIOA pins for SSI0 enable
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

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

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

        // SSI0 config
        SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
                           SSI_MODE_MASTER, 8000000, 8);

        // SSI0 enable
        SSIEnable(SSI0_BASE);


       while(SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0])); // ulDataRx - declared data table

        // SPI_inter_handler function will be an interrupt handler
        IntRegister(INT_SSI0, SPI_inter_handler);

        // SPI interrupt enable
        IntEnable(INT_SSI0);

        // SPI interrupt from receiving data
        SSIIntEnable(SSI0_BASE, SSI_RXFF);

        // Interrupt enable
        IntMasterEnable();

My questions are:

1. If I receive a byte will I have an interrupt? In DS we can read: "Receive FIFO service (when the receive FIFO is half full or more)". Since a Receive FIFO is 8x16 byte memory will the interrupt occur after 8 received bytes?

2. I've received the byte (or a few bytes) of data. How can I access to it?

3. Need I clear any flag in the interrupt?

4. If I configure a SPI interrupt also for data transmitting, how data transmission looks like?


I will grateful for a help.

Best regards,

Mikolaj


edit.:

In regard to 2nd question, I've found in DS description of the SSIDR register where 16-bit data is stored. Additionally there is a SSIDataGet

function in Stellaris Peripheral Driver Library. Should it be used in the interrupt?

  • Hello Mikolaj,

    Please find answers to your questions below.

    If I receive a byte will I have an interrupt?

    It depends on how you configure the interrupts. You can configure the RX to interrupt when

    • The receive FIFO is half full or more
    • Receive FIFO has timed out
    • Receive FIFO has overrun

    The Driverlib API SSIIntEnable() can be used to set the required interrupts.

    Since a Receive FIFO is 8x16 byte memory will the interrupt occur after 8 received bytes?

    If the RX is configured to interrupt when FIFO is half full or more, an interrupt would occur after receiving 8 or more bytes. What this means is after receiving 8 bytes the interrupt will fire at the next available opportunity. So by the time the processor has been interrupted, more than 8 bytes could have been received.

    I've received the byte (or a few bytes) of data. How can I access to it?

    Data can be read from the register SSIDR. Before reading the data it is advisable to check if “SSI Receive FIFO Not Empty” bit (present in SSISR register) is set. Alternatively, the Driverlib API SSIDataGet() returns the data received if SSI RX FIFO has data available.

    Need I clear any flag in the interrupt?

    For Tiva devices the interrupt bit that caused the interrupt must always be cleared. The Driverlib API SSIIntClear() can be used to clear the interrupts.

    If I configure a SPI interrupt also for data transmitting, how data transmission looks like?

    I don’t understand this question.

    Regards,
    Sainandan Reddy

  • Thank you for your answer.

    Let's take the simplest case: receiving and transmitting byte per byte. Suppose the SSI is correctly configured and a receive FIFO time-out interrupt is enabled.

    Please, look at my interrupt handler:

    void SPI_inter_handler(void){



        unsigned long int_source=SSIIntStatus(SSI0_BASE, true);
        unsigned long rx_data_size;

        SSIIntClear(SSI0_BASE,int_source);


        if(int_source & SSI_RXTO){       

            if(SEND_FLAG){
                SSIDataPutNonBlocking(SSI0_BASE, &data[TX_pointer]);
                TX_pointer++;

            }
            if(TX_pointer==set_value){    // Sending finished
                SSIIntDisable(SSI0_BASE, SSI_TXFF);

                SEND_FLAG=0;

            }
            rx_data_size=SSIDataGetNonBlocking(SSI0_BASE, &received_data[RX_pointer]);
            RX_pointer+=rx_data_size;
        }

    }

    Is it correct? SEND_FLAG, TX_pointer and RX_pointer are global variables.