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.

TMDSLCDK138: OMAP L138 SPI not working

Part Number: TMDSLCDK138
Other Parts Discussed in Thread: MATHLIB, OMAPL138

TMDSLCDK138 / tms320-xds100-v3 / CCS 7.4

I'm trying to get SPI1 working on the DSP side, not having much luck.  Not seeing anything on my oscope probes.  Here's some code:

// #defines for the OMAP L-138 timer registers
// see www.ti.com/.../omap-l138.pdf
// see www.ti.com/.../sprufm4i.pdf

#define SPI0 ((uint32_t *) 0x01C41000)
#define SPI1 ((uint32_t *) 0x01F0E000)

#define SPIGCR0 (0x00/sizeof(uint32_t)) // SPI Global Control Register 0 Section 3.1
#define SPIGCR0_RESET (1 << 0)

#define SPIGCR1 (0x04/sizeof(uint32_t)) // SPI Global Control Register 1 Section 3.2
#define SPIGCR1_ENABLE (1 << 24)
#define SPIGCR1_LOOPBACK (1 << 16)
#define SPIGCR1_POWERDOWN (1 << 8)
#define SPIGCR1_CLKMOD (1 << 1)
#define SPIGCR1_MASTER (1 << 0)

#define SPIINT0 (0x08/sizeof(uint32_t)) // SPI Interrupt Register Section 3.3
#define SPIINT0_ENABLEHIGHZ (1 << 24)
#define SPIINT0_DMAREQEN (1 << 16)
#define SPIINT0_TXINTENA (1 << 9)
#define SPIINT0_RXINTENA (1 << 8)
#define SPIINT0_OVRNINTENA (1 << 6)
#define SPIINT0_BITERRENA (1 << 4)
#define SPIINT0_DESYNCENA (1 << 3)
#define SPIINT0_PARERRENA (1 << 2)
#define SPIINT0_TIMEOUTENA (1 << 1)
#define SPIINT0_DLENERRENA (1 << 0)

#define SPILVL (0x0C/sizeof(uint32_t)) // SPI Interrupt Level Register Section 3.4
#define SPILVL_TXINTLVL (1 << 9)
#define SPILVL_RXINTLVL (1 << 8)
#define SPILVL_OVRNINTLVL (1 << 6)
#define SPILVL_BITERRLVL (1 << 4)
#define SPILVL_DESYNCLVL (1 << 3)
#define SPILVL_PAREERRLVL (1 << 2)
#define SPILVL_TIMEOUTLVL (1 << 1)
#define SPILVL_DLENERRLVL (1 << 0)

#define SPIFLG (0x10/sizeof(uint32_t)) // SPI Flag Register Section 3.5
#define SPIFLG_TXINTFLG (1 << 9)
#define SPIFLG_RXINTFLG (1 << 8)
#define SPIFLG_OVRNINTFLG (1 << 6)
#define SPIFLG_BITERRFLG (1 << 4)
#define SPIFLG_DESYNCFLG (1 << 3)
#define SPIFLG_PAREERRFLG (1 << 2)
#define SPIFLG_TIMEOUTFLG (1 << 1)
#define SPIFLG_DLENERRFLG (1 << 0)

#define SPIPC0 (0x14/sizeof(uint32_t)) // SPI Pin Control Register 0 (Function) Section 3.6
#define SPIPC0_SOMIFUN (1 << 11)
#define SPIPC0_SIMOFUN (1 << 10)
#define SPIPC0_CLKFUN (1 << 9)
#define SPIPC0_ENAFUN (1 << 8)
#define SPIPC0_SCS0FUN7 (1 << 7)
#define SPIPC0_SCS0FUN6 (1 << 6)
#define SPIPC0_SCS0FUN5 (1 << 5)
#define SPIPC0_SCS0FUN4 (1 << 4)
#define SPIPC0_SCS0FUN3 (1 << 3)
#define SPIPC0_SCS0FUN2 (1 << 2)
#define SPIPC0_SCS0FUN1 (1 << 1)
#define SPIPC0_SCS0FUN0 (1 << 0)

#define SPIPC1 (0x18/sizeof(uint32_t)) // SPI Pin Control Register 1 (Direction) Section 3.7
#define SPIPC1_SOMIDIR (1 << 11)
#define SPIPC1_SIMODIR (1 << 10)
#define SPIPC1_CLKDIR (1 << 9)
#define SPIPC1_ENADIR (1 << 8)
#define SPIPC1_SCS0DIR7 (1 << 7)
#define SPIPC1_SCS0DIR6 (1 << 6)
#define SPIPC1_SCS0DIR5 (1 << 5)
#define SPIPC1_SCS0DIR4 (1 << 4)
#define SPIPC1_SCS0DIR3 (1 << 3)
#define SPIPC1_SCS0DIR2 (1 << 2)
#define SPIPC1_SCS0DIR1 (1 << 1)
#define SPIPC1_SCS0DIR0 (1 << 0)

#define SPIPC2 (0x1C/sizeof(uint32_t)) // SPI Pin Control Register 2 (Input) Section 3.8
#define SPIPC2_SOMIDIN (1 << 11)
#define SPIPC2_SIMODIN (1 << 10)
#define SPIPC2_CLKDIN (1 << 9)
#define SPIPC2_ENADIN (1 << 8)
#define SPIPC2_SCS0DIN7 (1 << 7)
#define SPIPC2_SCS0DIN6 (1 << 6)
#define SPIPC2_SCS0DIN5 (1 << 5)
#define SPIPC2_SCS0DIN4 (1 << 4)
#define SPIPC2_SCS0DIN3 (1 << 3)
#define SPIPC2_SCS0DIN2 (1 << 2)
#define SPIPC2_SCS0DIN1 (1 << 1)
#define SPIPC2_SCS0DIN0 (1 << 0)

#define SPIPC3 (0x20/sizeof(uint32_t)) // SPI Pin Control Register 3 (Output) Section 3.9
#define SPIPC3_SOMIDOUT (1 << 11)
#define SPIPC3_SIMODOUT (1 << 10)
#define SPIPC3_CLKDOUT (1 << 9)
#define SPIPC3_ENADOUT (1 << 8)
#define SPIPC3_SCS0DOUT7 (1 << 7)
#define SPIPC3_SCS0DOUT6 (1 << 6)
#define SPIPC3_SCS0DOUT5 (1 << 5)
#define SPIPC3_SCS0DOUT4 (1 << 4)
#define SPIPC3_SCS0DOUT3 (1 << 3)
#define SPIPC3_SCS0DOUT2 (1 << 2)
#define SPIPC3_SCS0DOUT1 (1 << 1)
#define SPIPC3_SCS0DOUT0 (1 << 0)

#define SPIPC4 (0x24/sizeof(uint32_t)) // SPI Pin Control Register 4 (Set SPIPC3) Section 3.10
#define SPIPC4_SOMISET (1 << 11)
#define SPIPC4_SIMOSET (1 << 10)
#define SPIPC4_CLKSET (1 << 9)
#define SPIPC4_ENASET (1 << 8)
#define SPIPC4_SCS0SET7 (1 << 7)
#define SPIPC4_SCS0SET6 (1 << 6)
#define SPIPC4_SCS0SET5 (1 << 5)
#define SPIPC4_SCS0SET4 (1 << 4)
#define SPIPC4_SCS0SET3 (1 << 3)
#define SPIPC4_SCS0SET2 (1 << 2)
#define SPIPC4_SCS0SET1 (1 << 1)
#define SPIPC4_SCS0SET0 (1 << 0)

#define SPIPC5 (0x28/sizeof(uint32_t)) // SPI Pin Control Register 5 (Clear SPIPC3) Section 3.11
#define SPIPC5_SOMICLR (1 << 11)
#define SPIPC5_SIMOCLR (1 << 10)
#define SPIPC5_CLKCLR (1 << 9)
#define SPIPC5_ENACLR (1 << 8)
#define SPIPC5_SCS0CLR7 (1 << 7)
#define SPIPC5_SCS0CLR6 (1 << 6)
#define SPIPC5_SCS0CLR5 (1 << 5)
#define SPIPC5_SCS0CLR4 (1 << 4)
#define SPIPC5_SCS0CLR3 (1 << 3)
#define SPIPC5_SCS0CLR2 (1 << 2)
#define SPIPC5_SCS0CLR1 (1 << 1)
#define SPIPC5_SCS0CLR0 (1 << 0)

#define SPIDAT0 (0x38/sizeof(uint32_t)) // SPI Data Transmit Register 0 Section 3.12
#define SPIDAT0_TXDATA(x) ((x) & 0xFFFF)

#define SPIDAT1 (0x3C/sizeof(uint32_t)) // SPI Data Transmit Register 1 (Data Transmit and Format Select) Section 3.13
#define SPIDAT1_CSHOLD (1 << 28)
#define SPIDAT1_WDEL (1 << 26)
#define SPIDAT1_DFSEL(x) (((x) ^ 0x3) << 24)
#define SPIDAT1_CSNR7 (1 << 23)
#define SPIDAT1_CSNR6 (1 << 22)
#define SPIDAT1_CSNR5 (1 << 21)
#define SPIDAT1_CSNR4 (1 << 20)
#define SPIDAT1_CSNR3 (1 << 19)
#define SPIDAT1_CSNR2 (1 << 18)
#define SPIDAT1_CSNR1 (1 << 17)
#define SPIDAT1_CSNR0 (1 << 16)
#define SPIDAT1_TXDATA(x) ((x) & 0xFFFF)

#define SPIBUF (0x40/sizeof(uint32_t)) // SPI Receive Buffer Register Section 3.14
#define SPIBUF_RXEMPTY (1 << 31)
#define SPIBUF_RXOVR (1 << 30)
#define SPIBUF_TXFULL (1 << 29)
#define SPIBUF_BITERR (1 << 28)
#define SPIBUF_DESYNC (1 << 27)
#define SPIBUF_PARERR (1 << 26)
#define SPIBUF_TIMEOUT (1 << 25)
#define SPIBUF_DLENERR (1 << 24)
#define SPIBUF_RXDATA_MASK 0xFFFF

#define SPIEMU (0x44/sizeof(uint32_t)) // SPI Receive Emulation Register Section 3.15
#define SPIEMU_RXDATA_MASK 0xFFFF

#define SPIDELAY (0x48/sizeof(uint32_t)) // SPI Delay Register Section 3.16
#define SPIDELAY_C2TDELAY(x) (((x) & 0xFF) << 24)
#define SPIDELAY_T2CDELAY(x) (((x) & 0xFF) << 16)
#define SPIDELAY_T2EDELAY(x) (((x) & 0xFF) << 8)
#define SPIDELAY_C2EDELAY(x) (((x) & 0xFF) << 0)

#define SPIDEF (0x4C/sizeof(uint32_t)) // SPI Default Chip Select Register Section 3.17
#define SPIDEF_CSDEF7 (1 << 7)
#define SPIDEF_CSDEF6 (1 << 6)
#define SPIDEF_CSDEF5 (1 << 5)
#define SPIDEF_CSDEF4 (1 << 4)
#define SPIDEF_CSDEF3 (1 << 3)
#define SPIDEF_CSDEF2 (1 << 2)
#define SPIDEF_CSDEF1 (1 << 1)
#define SPIDEF_CSDEF0 (1 << 0)

#define SPIFMT0 (0x50/sizeof(uint32_t)) // SPI Data Format Register 0 Section 3.18
#define SPIFMT1 (0x54/sizeof(uint32_t)) // SPI Data Format Register 1 Section 3.18
#define SPIFMT2 (0x58/sizeof(uint32_t)) // SPI Data Format Register 2 Section 3.18
#define SPIFMT3 (0x5C/sizeof(uint32_t)) // SPI Data Format Register 3 Section 3.18
#define SPIFMTn_WDELAY(x) (((x) & 0x3F) << 24)
#define SPIFMTn_PARPOL (1 << 23)
#define SPIFMTn_PARENA (1 << 22)
#define SPIFMTn_WAITENA (1 << 21)
#define SPIFMTn_SHIFTDIR (1 << 20)
#define SPIFMTn_DISCSTIMERS (1 << 18)
#define SPIFMTn_POLARITY (1 << 17)
#define SPIFMTn_PHASE (1 << 16)
#define SPIFMTn_PRESCALE(x) (((x) & 0xFF) << 8)
#define SPIFMTn_CHARLEN(x) (((x) & 0x1F) << 0)

#define INTVEC0 (0x60/sizeof(uint32_t)) // SPI Interrupt Vector Register 1 Section 3.19
// TODO FIX this register is not documented!

#define INTVEC1 (0x64/sizeof(uint32_t)) // SPI Interrupt Vector Register 1 Section 3.19
#define INTVEC1_INTVECT1(x) (((x) & 0x1F) << 1)

void enable_spi(void) {
UInt32* PINMUX =(UInt32*)0x01C14120;
PINMUX[5] = (PINMUX[5] & 0xFF00F00F) | 0x00110110; // enables SPI1 & CS0

// per www.ti.com/.../sprufm4i.pdf pg 13

SPI1[SPIGCR0] = SPIGCR0_RESET;
SPI1[SPIGCR1] = SPIGCR1_CLKMOD | SPIGCR1_MASTER;
SPI1[SPIPC0] = SPIPC0_SOMIFUN | SPIPC0_SIMOFUN | SPIPC0_CLKFUN | SPIPC0_SCS0FUN0;

SPI1[SPIINT0] = 0; // no interrupts, we'gonna block, because we just do setup
SPI1[SPILVL] = 0; // again, no interrupts
// SPI1[SPIFLG] = 0; // no need to set
// SPI1[SPIPC1] = 0; // no need to set
// SPI1[SPIPC2] = 0; // read only register,do NOT set
// SPI1[SPIPC3] = 0; // no need to set
// SPI1[SPIPC4] = 0; // no need to set
// SPI1[SPIPC5] = 0; // no need to set

// these delay values are pure guesswork
// no T2E or C2E, because we're not using the ENA function
SPI1[SPIDELAY] = SPIDELAY_C2TDELAY(3) | SPIDELAY_T2CDELAY(3);

// CS normally high when inactive
SPI1[SPIDEF] = 0xFF;

// PRESCALE here is pure guesswork. CHARLEN is correct.
SPI1[SPIFMT0] = SPIFMTn_PRESCALE(8) | SPIFMTn_CHARLEN(16);
SPI1[SPIFMT1] = SPIFMTn_PRESCALE(8) | SPIFMTn_CHARLEN(16);
SPI1[SPIFMT2] = SPIFMTn_PRESCALE(8) | SPIFMTn_CHARLEN(16);
SPI1[SPIFMT3] = SPIFMTn_PRESCALE(8) | SPIFMTn_CHARLEN(16);

// set ENABLE *last*
SPI1[SPIGCR1] |= SPIGCR1_ENABLE;

while(1) {
SPI1[SPIDAT0] = 0x0A00; // I expect to see continuous o'scope activity

}
}

Here's some other information I'm not sure is relevant, but TI folks always ask:

bios_6_52_00_12/
ccsv7/
cg_xml/
'Code Composer Studio 7.4.0.lnk'*
dsplib_c674x_3_4_0_0/
edma3_lld_2_12_05_30C/
ipc_3_47_01_00/
mathlib_c674x_3_1_1_0/
mathlib_c674x_3_1_2_1/
mathlib_rts_c674x_3_1_2_1/
ndk_2_26_00_08/
pdk_omapl138_1_0_4/
processor_sdk_rtos_omapl138_4_03_00_05/
ti-cgt-arm_16.9.3.LTS/
ti-cgt-c6000_8.2.2/
tirex-product-tree/
uia_2_21_02_07/
xdais_7_24_00_04/
xdctools_3_32_02_25_core/
xdctools_3_50_03_33_core/
xdctools_3_50_04_43_core/
xdctools_3_50_05_12_core/