Quantcast
Channel: Processors forum - Recent Threads
Viewing all articles
Browse latest Browse all 17527

OMAP L138 SPI1 Problems

$
0
0

Hello All,

I am using LogicPD Omap L138 SOM on a custom board, SysBios 6.34.2.18, XDCTools 3.23.5.61, StarterWare 1.10.03.03.

I try communicating with a sensor trough SPI1 over the ARM9 core:

1. Pinmux is configured correctly (PINMUX4 = 0x01000000, PINMUX5 = 0x00110100)

2. CS 3 is used

3. SPI Freq is 350KHz

4. Char length is 16bits, MSB first, Polarity HIGH, Phase LOW (As the sensor DS requires).

I have some problems:

1. SOMI line is LOW when no data is transferred but when data is transferred it is pulled HIGH (I can see some data higher than the flat line). I looked into LogicPD SOM schematics also in my custom board and couldn't find any interference. 

2. Why do the processor send ~64 clocks for 2 bytes of transferred data? (Shouldn't it be 16 clocks for send and 16 clocks for receive?).

Here is my code:

#define SIMO_SOMI_CLK_CS        0x00000E00
#define CHAR_LENGTH             0x10
#define CSNum 		3//2
#define SPI_INT		SYS_INT_SPINT1
#define SPI_BASE	SOC_SPI_1_REGS

volatile unsigned int flag = 1;
volatile unsigned int is_ok = 0;
volatile unsigned char tx_flag = 0;
int len;
unsigned int tx_len;
unsigned int rx_len;
unsigned int tx_data[2000];
unsigned int rx_data[26000];
#pragma DATA_SECTION(tx_data,"EXTRAM");
#pragma DATA_SECTION(rx_data,"EXTRAM");
unsigned int *p_tx;
unsigned int *p_rx;

Void main()
{ 
    Task_Params taskParams;

    /* Create two tasks that share a resource*/
    Task_Params_init(&taskParams);
    taskParams.priority = 1;
    tsk1 = Task_create (task1, &taskParams, NULL);

    SPIInitialize();
    BIOS_start();
}
/******************************************************************************
**                      INTERNAL FUNCTION DEFINITIONS
*******************************************************************************/
Void task1(UArg arg0, UArg arg1)
{
    ReadData();

    while(rx_len<128)
    {
    }
}
void ReadData(void)
{
    tx_data[0] = 100; // This asks the sensor for config data, Data is received from external interrupt.
    len = 1;
    SPIDat1Config(SPI_BASE, (SPI_CSHOLD | SPI_DATA_FORMAT0), DCS);
    SpiTransfer();
}

/*
** Enables SPI Transmit and Receive interrupt.
** Deasserts Chip Select line.
*/
void  SpiTransfer(void)
{
    p_tx = &tx_data[0];
    p_rx = &rx_data[0];
    SPIIntEnable(SPI_BASE, (SPI_RECV_INT | SPI_TRANSMIT_INT));
    while(flag);
    flag = 1;
    /* Deasserts the CS pin(line) */
    //SPIDat1Config(SOC_SPI_1_REGS, SPI_DATA_FORMAT0, DCS);
}

/*
** Data transmission and receiption SPIIsr
**
*/
void SPIIsr(void)
{
    IntSystemStatusClear(SPI_INT);
    unsigned int intCode = SPIInterruptVectorGet(SPI_BASE);

    while (intCode)
    {
        if(intCode == SPI_TX_BUF_EMPTY)
        {
            len--;
            SPITransmitData1(SPI_BASE, *p_tx);
            p_tx++;
            if (!len)
            {
                SPIIntDisable(SPI_BASE, SPI_TRANSMIT_INT);
            }
        }

        if(intCode == SPI_RECV_FULL)
        {
        	int rec = SPIDataReceive(SPI_BASE);
        	*p_rx = (short)rec;
        	p_rx++;
        	rx_len++;
        	if (!len)
        	{
        		flag = 0;
        		SPIIntDisable(SPI_BASE, SPI_RECV_INT);
        	}
        }
        intCode = SPIInterruptVectorGet(SPI_BASE);
    }
}

/*
** Configures Data Format register of SPI
**
*/
void SPIConfigDataFmtReg(unsigned int dataFormat, unsigned int baseAdd)
{
    SPIConfigClkFormat(baseAdd,
                       (SPI_CLK_POL_HIGH | SPI_CLK_INPHASE),
                       dataFormat);

    /* Configures SPI to transmit MSB bit First during data transfer */
    SPIShiftMsbFirst(baseAdd, dataFormat);

    /* Sets the Charcter length */
    SPICharLengthSet(baseAdd, CHAR_LENGTH, dataFormat);
}

/*
** Initialization of SPI1 Instance is done here.
*/
void SPIInitialize(void)
{
	flagTx = 0;
	flagRx = 0;
	int spiInstance = 0;
#ifndef SPI_0
	spiInstance = 1;
#endif

	if(spiInstance == 0)
	{
		PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_SPI0, PSC_POWERDOMAIN_ALWAYS_ON,
				PSC_MDCTL_NEXT_ENABLE);
	}
	else if(spiInstance==1)
	{
		PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_SPI1, PSC_POWERDOMAIN_ALWAYS_ON,
				PSC_MDCTL_NEXT_ENABLE);
	}

    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON,
                     PSC_MDCTL_NEXT_ENABLE);

    /* Using SPI1 instance. */
    SPIPinMuxSetup(spiInstance);

    /* Select CS0 of SPI0. The SPI Flash is connected to SPI0_SCS[0]. */
	if(spiInstance == 0)
	{
	    SPI0CSPinMuxSetup(CSNum);
	}
	else if(spiInstance==1)
	{
	    SPI1CSPinMuxSetup(CSNum);
	}

    SPISetUp(SPI_BASE);
}

/*
** Configures the SPI1 instance for communication.
*/
void SPISetUp(unsigned int baseAdd)
{
    unsigned int  val = SIMO_SOMI_CLK_CS | DCS;

    SPIReset(baseAdd);

    SPIOutOfReset(baseAdd);

    SPIModeConfigure(baseAdd, SPI_MASTER_MODE);

    SPIPinControl(baseAdd, 0, 0, &val);

    /* Configures SPI Data Format Register */
    SPIConfigDataFmtReg(SPI_DATA_FORMAT0, baseAdd);

    SPIDefaultCSSet(baseAdd, DCS);

    SPIClkConfigure(baseAdd, SOC_SPI_1_MODULE_FREQ, 350000, SPI_DATA_FORMAT0);

     /* Selects the SPI Data format register to used and Sets CSHOLD
      * to assert CS pin(line)
      */
    SPIDat1Config(baseAdd, (SPI_CSHOLD | SPI_DATA_FORMAT0), DCS);

     /* map interrupts to interrupt line INT1 */
    SPIIntLevelSet(baseAdd, SPI_RECV_INTLVL | SPI_TRANSMIT_INTLVL);

    HWREG(baseAdd + SPI_SPIPC(1)) |= (0x00000600 | DCS);

    /* Enable SPI communication */
    SPIEnable(baseAdd);
}

Thanks for the help,

Yoel


Viewing all articles
Browse latest Browse all 17527

Trending Articles