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.

CC2640: Generating an interrupt from SPI CS

Part Number: CC2640

Hi

I have a application that requires to know when the SPI transfer has started. The SPI driver is in slave mode and is using a callback on CS rising to process the incoming data, this all works fine.

The application is required to notify the connected system that the SPI is busy and processing has not completed. I require to de-assert a READY signal as soon as the SPI CS falling edge is detected. When I try to configure the pin being used for SPI CS for falling edge interrupt, the SPI driver no longer works? 

Does anyone know how to configure the peripheral pin so that the input interrupt can also be generated.

Thanks

  • Mark,

    It sounds like there is an issue with the SPI driver and trying to attach another interrupt. Can you share how your SPI is configured, along with how the CS is configured?

    Have you looked at the TI Driver SPI examples?

    This examples shows how to use a MASTER_READY and SLAVE_READY GPIO as part of the SPI driver.

    Regards,

    Daniel

  • This use case is out of band signalling between the two systems and using the falling edge of the master CS is a very convenient place to get the start of processing without adding further lines. The SPI is fully working on the CS rising callback from within the SPI driver.

    Here is the default Pin configuration

     const PIN_Config BoardGpioInitTable[] = {

    Board_RLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX, /* LED initially off */
    Board_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX, /* LED initially off */
    Board_BLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX, /* LED initially off */
    Board_UART_RX | PIN_INPUT_EN | PIN_PULLDOWN, /* UART RX via debugger back channel */
    Board_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL, /* UART TX via debugger back channel */

    Board_SPI1_MISO | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL, /* SPI slave out - master in */
    Board_SPI1_MOSI | PIN_INPUT_EN | PIN_PULLUP, /* SPI slave in - master out */
    Board_SPI1_CSN | PIN_INPUT_EN | PIN_PULLUP | PIN_BM_HYSTERESIS | PIN_IRQ_NEGEDGE, // SPI slave chip select, enable interrupt on falling edge
    Board_SPI1_CLK | PIN_INPUT_EN | PIN_PULLUP , /* SPI slave clock */

    Board_READY | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN, // Ready signal for data transfer (open drain)
    Board_WAITING | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_OPENDRAIN, // Waiting signal for message to arrive (open drain)

    Board_TP2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN, /* Debug IO initially high */
    Board_TP3 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN, /* Debug IO initially high */

    PIN_TERMINATE
    };

    This is the SPI initialisation code


    SPI_init();

    SPI_Handle handle;
    SPI_Params params;
    SPI_Transaction transaction;

    // Init SPI and specify non-default parameters
    SPI_Params_init(&params);
    params.frameFormat = SPI_POL1_PHA1;
    params.mode = SPI_SLAVE;
    params.transferMode = SPI_MODE_CALLBACK;
    params.transferCallbackFxn = serialRxCallback;

    // Open the SPI and initiate the partial read
    handle = SPI_open(Board_SPI1, &params);
    if(!handle) {
    System_printf("SPI1 did not open");
    }

    // Enable RETURN_PARTIAL
    SPI_control(handle, SPICC26XXDMA_RETURN_PARTIAL_ENABLE, NULL);

    When I try to add the additional configuration in the application file as soon as I configure the pin the SPI fails. As I need a handle for pin to register the callback

    static PIN_Config pinTable[] = {
    Board_READY | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN, // Ready signal for data transfer
    // Board_SPI1_CSN | PIN_INPUT_EN | PIN_PULLUP | PIN_BM_HYSTERESIS | PIN_IRQ_NEGEDGE, // SPI slave chip select, enable interrupt on falling edge
    PIN_TERMINATE
    };

    hspiPins = PIN_open(&pinState, pinTable);
    //PIN_registerIntCb(hspiPins, serialCSCallback);

    Thanks

  • I have checked the examples and this is not what I am looking for. These effectively hold off until SPI is ready at both ends. The signal I need to generate is set when the CS falling edge is received and is cleared once the the local processing that occurs after the CS rising has completed.

                     ___        _________________
    Master SPI CS       |______|

                         ______________
    Slave mySIG     ____|              |_________

    Xfer Start ---------^
    Xfer End ------------------^
    Slave Process Start ---------^
    Slave Process End------------------^

    This allows the master not make a further transfer until after the slave has completed processing. Driving mySIG after the CS rising edge means there is a point at which the master will see the mySIG line in the wrong state and may transfer early by misreading the line before starting a transfer. Hence the need to operate the slave on the CS falling edge.

  • Thanks for the clarification, Mark.

    I believe the issue you are seeing is that you essentially have 2 Pin Tables pointing to the same GPIO. In this scenario, the last one that is opened initialized will "control" the pin.

    Generally you cannot have 2 different callback functions associated to a single pin/gpio.

    Instead, you can try to set the pin to PIN_IRQ_BOTHEDGES and then within the callback, have logic to determine rising or falling edge of the CS line.

    Regards,

    Daniel

  • Just to be really clear before I go and hack my code. The first table is the default PIN table used to set the pins at startup, as i understand it, this is used as the state when the pin is closed. The second table is within the application and allows me to assign a callback once the pin is open.

    If I use the pin as a GPIO with both edge interrupts (the SPI driver will no longer action it's callback) I assume I must then abort the SPI transfer to gather the incoming data?

    Thanks

  • Mark,

    The problem is that by having the second pin table with the attached interrupts overwrite the original pin configuration, the pin is no longer controlled by the SPI driver. So if you want to have a second pin table to configure callbacks and interrupts you will need to manage the CS pin in software.

    Regards,

    Daniel