This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SSP vs SPI - interrupt code not compatible

Hey,
Thinking that the SSP and SPI interfaces are the same, I wrote the code for SSP slavemode interrupt.
But then found out that there is a difference. The CS(SSEL) line in SPI remains low for whole frame transfer, in SSP but it toggles after each frame (a frame = 4-16bits _configurable_) in SSP. (SPI frame can be of 'n' no of bytes)
So at the master, i modified the CS to act as GPIO and toggle the line after every byte transfer.

Now the problem is that if i process interrupt after receiving of each data byte the code generates an os_error. Hence (referring an example code) i had to implement the data transfer in a while loop as in the code below:

while( (SSPx->SR & SSP_SR_RNE) || (SSPx->SR & SSP_SR_TFE) || (dataCfg->tx_cnt != dataCfg->length))
{
        tmp = SSP_ReceiveData(SSPx);

        if(tmp == SPI_SOF)
        {
                dataCfg->rx_cnt = 0;
                dataCfg->tx_cnt = 0;
                dataCfg->status = SPI_STATUS_SOF;
        }

        if(dataCfg->tx_data == NULL)
        {
                SSP_SendData(SSPx, 0xFF);
                dataCfg->tx_cnt++;
        }
        else
        {
                SSP_SendData(SSPx, (*(uint8_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt)));
                dataCfg->tx_cnt++;
        }

        // Store data to destination
        //if (dataCfg->rx_data != NULL)
        {
                *(uint8_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint8_t) tmp;
                        dataCfg->rx_cnt++;
        }

        // Check error
        if ((stat = SSPx->RIS) & SSP_RIS_ROR)
        {
                // save status and return
                dataCfg->status = stat | SSP_STAT_ERROR;
                return;
        }
}


os_error = 2, which indicates that the interrupt occurance is too fast.

CPOL = 0, CPHA = 1.

performing the data transfer in while loop, causes loss of synchronization. Cant figure out how to solve this.
The master clock frequency = 250KHz. Master is a microchip IC (whose code worked well with SPI protocol of LPC1768).


  • "Thinking that the SSP and SPI interfaces are the same"

    On what basis? Certainly, SPI implementations are not the same across all chips - sometimes not even across aparently similar chips from the same manufacturer!

    What is "SSP"?

  • On what basis?
    Well...
    The SSP is a Synchronous Serial Port (SSP) controller capable of operation on a SPI,
    4-wire SSI, or Microwire bus (as is from the usermanual)
    _the more important reason_

    SPI implementations are not the same across all chips - sometimes not even across aparently similar chips from the same manufacturer
    astonished.

  • It ia AMAZING that many OP's do not have the ability to answer even the simplest questions

    Erik

  • Why are you looping in an interrupt?
    Did you configure SSP to operate in SPI mode?
    What make you think the behavior should be compatible? Just follow the instructions of the user manual regarding interrupt handling.
    Where is the difficulty?

  • And astonished that you should be so!

    But I think there may be some confusion here between "SPI" as in the external interface - with MISO, MOSI, CLK & SS lines - and the peripheral block within the microcontroller which manages the external SPI.

    Sure, the external interface has to be compatible across different chips - but that does not mean that the internal peripheral blocks within the chips have to be the same.

    In fact, a quick read of a few datasheets will soon show that they are not the same - different register sets, different interrupts, different options, etc, etc.

    And it's the internal peripheral blocks that your software deals with...

  • You quoted this:

    "The SSP is a Synchronous Serial Port (SSP) controller capable of operation on a SPI, 4-wire SSI, or Microwire bus"

    That certainly does not say that "SSP" is the same thing as "SPI"!

  • Hi Dhaval Solanki,

    I am not so sure, but maybe you should re-read the user manual, and re-consider you options.

    For LPC1788,
    UM10470
    Chapter 21: LPC178x/7x SSP interfaces
    Page 623:
    21.6.1 SSPn Control Register 0

    Bit    Symbol    Value    Description
    Value
    
    
    5:4    FRF                Frame Format.
                     00         SPI
                     01         TI
                     10         Microwire
                     11         This combination is not supported and should not be used.
    
    6      CPOL               Clock Out Polarity. This bit is only used in SPI mode. 0
                     0          SSP controller maintains the bus clock low between frames.
                     1          SSP controller maintains the bus clock high between frames.
    7      CPHA               Clock Out Phase. This bit is only used in SPI mode. 0
                                0 SSP controller captures serial data on the first clock transition of the frame, that is, the
                                  transition away fromthe inter-frame state of the clock line.
                                1 SSP controller captures serial data on the second clock transition of the frame, that is, the
                                  transition back tothe inter-frame state of the clock line.
    

  • Why are you looping in an interrupt?
    Now the problem is that if i process interrupt after receiving of each data byte the code generates an os_error. Hence (referring an example code) i had to implement the data transfer in a while loop (as already answered in the 1st post)

    What make you think the behavior should be compatible?
    (directly copy pasted from the user manual)
    Compatible with Motorola SPI, 4-wire TI SSI, and National Semiconductor Microwire
    buses.
    Synchronous Serial Communication.
    Master or slave operation.

    Just follow the instructions of the user manual regarding interrupt handling.
    The user manual has not specified anything in regards to writing interrupt handler code.

  • That certainly does not say that "SSP" is the same thing as "SPI"!
    Agreed Andrew. My mistake.

    may be some confusion here between "SPI" as in the external interface - with MISO, MOSI, CLK & SS lines - and the peripheral block within the microcontroller which manages the external SPI.
    Ya there was confusion.

    different register sets, different interrupts, different options, etc, etc.
    I had assumed this before starting with SSP. But had thought that the interrupts may be generated almost like in the SPI peripheral block - i mean to say an "SPI transfer complete flag" and atleast a related SPI interrupt.

    @John
    Thanks for pointing that out, mate.
    But i have already configured SSPn control register0 in SPI, CPOL = 0, CPHA = 1.
    It is with the interrupts and the interrupt handling function that i am facing problems with.

    As i was facing an os_error (number 2 - which indicates that "The interrupt rate for isr_xxx function calls is too fast. or Too many isr_xxx function calls from the same interrupt handler.)
    So to solve this, i have also tried using a dedicated DMA channel. But the data transfer synchronization is lost.
    Either the sync is lost or the os_error.
    sync is lost, either in the transmission frame or in the reception frame but not in both.
    Unfortunately i can not put break-points and debugg both the controllers simultaneously. (Disappointing)

    sync is lost, either in the transmission frame or in the reception frame but not in both.
    If this is a full-duplex protocol, then shouldmt sync loss be in both the frames?

  • by sycn loss, i mean, if i transmit tx_buff[0], then i must receive a byte in rx_buff[0].

  • I still do not see what chip
    Well, in that case, John Linq - Hats Off to you mate (how did you figured out).

    @Erik, Sorry. its LPC1788.

    Thank you Erik for all the concern and efforts that you are putting to help me. But i have figured out the solution. Appreciate your efforts.

    PS: Ain't we trolling?

  • Why not use the FIFO functionality? Then you don't get one receive and one write interrupt for every word transfer.

    By the way - I wouldn't bother to inform the OS about every byte transmitted in case I know I am transmitting a package. I would do the full transfer until the slave select signal gets deactivated and then inform whatever thread that one message is ready.

  • Why not use the FIFO functionality? Then you don't get one receive and one write interrupt for every word transfer.

    By the way - I wouldn't bother to inform the OS about every byte transmitted in case I know I am transmitting a package. I would do the full transfer until the slave select signal gets deactivated and then inform whatever thread that one message is ready.

  • Why not use the FIFO functionality? Then you don't get one receive and one write interrupt for every word transfer.

    By the way - I wouldn't bother to inform the OS about every byte transmitted in case I know I am transmitting a package. I would do the full transfer until the slave select signal gets deactivated and then inform whatever thread that one message is ready.

  • Note that you can use FIFO to reduce the number of interrupts. The SSP is way more capable than the very stupid SPI device.

    And if you are sending messages, then there is no reason to inform the OS about each individual word transfer - it's enough to send an event when the transfer ends, to let the relevant task pick up the result and consider what new message to send.

    If you are the receiver, then you can consider waiting with informing the thread until the slave select gets deactivated - unless you have a protocol that is doing the bad thing of keeping slave select active and sending both a question and expecting the slave to think and prepare a response on-the-fly within the same slave-select cycle.

    It's harder to be the slave, but the chip is able to run several MBit/s as slave.