Other Parts Discussed in Thread: SYSBIOS, OMAPL138
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