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