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.

am335x SPI in 3-wire mode not working

Hi,

for my application I would like to run the AM335x SPI in 3-wire mode on the ICE EVM board. The reason for this is that I would like to use the SPI0_CS1 pin for GPIO input to trigger an interrupt (on the ICE board not a lot of GPIO is accessible on the expansion header).

However, when I disable chip select using McSPICSDisable, the data transmission is not triggered. I use the following code, as derived from McSPIFlash (for now without GPIO):

#include "soc_AM335x.h"
#include "evmAM335x.h"
#include "interrupt.h"
#include "hw_types.h"
#include "mcspi.h"

#define MCSPI_OUT_FREQ                    (1500000u)
#define MCSPI_IN_CLK                     (48000000u)

static void ModulesConfigure(void);
static void IntConfigure(void);
static void McSPIIsr(void);

unsigned int chNum = 1;
unsigned char outbyte = 0xaa;

unsigned int length = 0;
unsigned char rxBuffer[260];
unsigned char *p_rx;
unsigned char txBuffer[260];
unsigned char *p_tx;
volatile unsigned int flag = 1;
unsigned int i = 0;
unsigned char cs = 0;

void main(void) {

    ModulesConfigure();

    // Map Interrupts to AINTC
    IntConfigure();

    // Disable chip select pin.
    cs = 0;
    if (cs){
        McSPICSEnable(SOC_SPI_0_REGS);
        McSPI0CSPinMuxSetup(chNum);
        McSPICSPolarityConfig(SOC_SPI_0_REGS, MCSPI_CS_POL_LOW, chNum);
    } else{
        McSPICSDisable(SOC_SPI_0_REGS);
    }

    while (1){
        txBuffer[0] = outbyte;
        length = 1;
        p_tx = txBuffer;
        p_rx = rxBuffer;

        if (cs){        /* SPIEN line is forced to low state.*/
            McSPICSAssert(SOC_SPI_0_REGS, chNum);
        }

        /* Enable the Tx/Rx interrupts of McSPI.*/
        McSPIIntEnable(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum) |
                       MCSPI_INT_RX_FULL(chNum));

        /* Enable the McSPI channel for communication.*/
        McSPIChannelEnable(SOC_SPI_0_REGS, chNum);

        /* Wait until control returns back from McSPI ISR.*/
        while(flag);

        flag = 1;


        /* Force SPIEN line to the inactive state.*/
        if (cs){
            McSPICSDeAssert(SOC_SPI_0_REGS, chNum);
        }

        /* Disable the McSPI channel.*/
        McSPIChannelDisable(SOC_SPI_0_REGS, chNum);
    }
}

static void ModulesConfigure(void){

    // Enable the clocks for McSPI0 module.
    McSPI0ModuleClkConfig();

    // Perform Pin-Muxing for SPI0 Instance
    McSPIPinMuxSetup(0);



    // Reset the McSPI instance.
    McSPIReset(SOC_SPI_0_REGS);

    // Enable master mode of operation.
    McSPIMasterModeEnable(SOC_SPI_0_REGS);

    // Perform the necessary configuration for master mode.
    McSPIMasterModeConfig(SOC_SPI_0_REGS, MCSPI_SINGLE_CH,
                          MCSPI_TX_RX_MODE, MCSPI_DATA_LINE_COMM_MODE_1,
                          chNum);

    // Configure the McSPI bus clock depending on clock mode.
    McSPIClkConfig(SOC_SPI_0_REGS, MCSPI_IN_CLK, MCSPI_OUT_FREQ, chNum,
                   MCSPI_CLK_MODE_0);

    // Configure the word length.
    McSPIWordLengthSet(SOC_SPI_0_REGS, MCSPI_WORD_LENGTH(8), chNum);
    /* Set polarity of SPIEN to low.*/


    /* Enable the transmitter FIFO of McSPI peripheral.*/
    McSPITxFIFOConfig(SOC_SPI_0_REGS, MCSPI_TX_FIFO_ENABLE, chNum);

    /* Enable the receiver FIFO of McSPI peripheral.*/
    McSPIRxFIFOConfig(SOC_SPI_0_REGS, MCSPI_RX_FIFO_ENABLE, chNum);
}

/* Interrupt mapping to AINTC and registering McSPI ISR */
static void IntConfigure(void)
{
    // Enable IRQ in CPSR.
    IntMasterIRQEnable();
    // Initialize ARM interrupt controller
    IntAINTCInit();

    // Register McSPIIsr interrupt handler
    IntRegister(SYS_INT_SPI0INT, McSPIIsr);

    // Set Interrupt Priority
    IntPrioritySet(SYS_INT_SPI0INT, 0, AINTC_HOSTINT_ROUTE_IRQ);

    // Enable system interrupt in AINTC
    IntSystemEnable(SYS_INT_SPI0INT);
}


/*
** McSPI Interrupt Service Routine. This function will clear the status of the
** Tx/Rx interrupts when generated. Will write the Tx data on transmit data
** register and also will put the received data from receive data register to
** a location in memory.
*/
static void McSPIIsr(void)
{

    unsigned int intCode = 0;

    intCode = McSPIIntStatusGet(SOC_SPI_0_REGS);

    while(intCode)
    {
        if(MCSPI_INT_TX_EMPTY(chNum) == (intCode & MCSPI_INT_TX_EMPTY(chNum)))
        {
            McSPIIntStatusClear(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum));

            length--;

            McSPITransmitData(SOC_SPI_0_REGS,(unsigned int)(*p_tx++), chNum);

            if(!length)
            {
                McSPIIntDisable(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum));

                McSPIIntStatusClear(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum));
            }
        }

        if(MCSPI_INT_RX_FULL(chNum) == (intCode & MCSPI_INT_RX_FULL(chNum)))
        {
            McSPIIntStatusClear(SOC_SPI_0_REGS, MCSPI_INT_RX_FULL(chNum));

            *p_rx++ = (unsigned char) McSPIReceiveData(SOC_SPI_0_REGS, chNum);

            if(!(length))
            {
                McSPIIntDisable(SOC_SPI_0_REGS, MCSPI_INT_RX_FULL(chNum));

                flag = 0;
            }
        }

        intCode = McSPIIntStatusGet(SOC_SPI_0_REGS);
    }
}

if I set cs to 1, I can see the output on the scope, however if I set it to 0, no transmission occurs. I also tried with chNum = 0 and cs = 0, but this does not help.

What's wrong?

Thank you,

Manuel