I am using a MCIMX536AVV8C custom board borrowed from a previous project with a working product, and am attempting to write a new SPI driver for my c application. Using a scope when I transmit SPI, I can see good data goes out on the MOSI and good data comes back on the MISO. The observed signal swings from 0 to 3.3 volts correctly. However, the RXDATA register is always zero.
I have tried moving the wiring to CSPI port, same issue. RXDATA is always 0x00. I also tried setting the MISO pin mux to GPIO as an input. It functions as expected when I inject a signal, so at least I know my wiring is good. But when configured as MISO, I inject 3.3 volts during the SPI transfer and still read 0x00 in the buffer.
Code is below.
void InitializeECSPI2 (void)
{
//MUX
IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT8_bit.MUX_MODE = 3; //T1 ECSPI2 CLK
IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT9_bit.MUX_MODE = 3; //R4 ECSPI2 MOSI
IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT10_bit.MUX_MODE = 3; //R5 ECSPI2 MISO
IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT10 = 0x1C4; //R5, Pull Down (input)
ECSPI2_CONREG_bit.CHANNEL_SELECT = 0;
//clock
ECSPI2_CONREG_bit.PRE_DIVIDER = 0;
ECSPI2_CONREG_bit.POST_DIVIDER = 9; // (9) divide by 512
/* all channels set to master mode */
ECSPI2_CONREG_bit.CHANNEL_MODE = 0xF; //set all channels
/* Set LEN bits to transfer. */
ECSPI2_CONREG_bit.BURST_LENGTH = 7;
/* Disable SPI to reset */
ECSPI2_CONREG_bit.EN = 1;
/* clear the bit */
ECSPI2_CONFIGREG_bit.SCLK_PHA = 0;
ECSPI2_CONFIGREG_bit.SCLK_POL = 0;
/* set the bit */
ECSPI2_CONFIGREG_bit.SS_CTL = 1 ;
/* Chip select polarity 0 = active low */
ECSPI2_CONFIGREG_bit.SS_POL = 0;
/* Set DATA to say low between xfers */
ECSPI2_CONFIGREG_bit.DATA_CTL = 1;
/* Set SCLK to say low between xfers */
ECSPI2_CONFIGREG_bit.SCLK_CTL = 0;
/* Set LEN bits to tradevnsfer. */
ECSPI2_CONFIGREG_bit.HT_LENGTH = 0xF;
ECSPI2_CONREG_bit.HT = 0;
/* Enable transfer complete interrupt */
ECSPI2_INTREG_bit.TCEN = 1;
/* Enable RX FIFO overflow interrupt */
ECSPI2_INTREG_bit.ROEN = 1;
/* Enable TX FIFO empty interrupt */
ECSPI2_INTREG_bit.TEEN = 1;
/* Set XCH mode (waits for flag before sending) */
ECSPI2_CONREG_bit.SMC = 0;
}
uint32_t ECSPI2Transfer( uint8_t tx_byte, uint8_t rx_expected )
{
//note: CS is set outside of the tx function
uint32_t receiveData = 0;
ECSPI2_CONREG_bit.BURST_LENGTH = 7;
ECSPI2_CONREG_bit.CHANNEL_SELECT = 0;
ECSPI2_CONREG_bit.EN = 1; /* enable spi */
ECSPI2_TXDATA = tx_byte; /* Tx data */
ECSPI2_CONREG_bit.XCH = 1; /* set xch bit */
/* poll on the TC bit (transfer complete) */
while (ECSPI2_STATREG_bit.TC == 0);
ECSPI2_STATREG_bit.TC = 1; /* Reset TC bit */
receiveData = ECSPI2_RXDATA;
return (receiveData); //receivedString
}
Mysterious side note. When I flash the binary from the previous working application, let run, then without power cycling I download my application to ram, I do get non-zero RXDATA in the buffer. The numbers in RXDATA are wrong, but unlike my naked application, they are not 0x00. It appears that the MISO input is reading any number of 0s, but only the first low to high transition. Afterward, it only reads 1s and misses any high to low transitions. Examples: 00,55,AA becomes 00,7F,FF, and 00,00,30 becomes 00,00,3F.
This is also wrong, but at least it is not nothing. Makes me suspect that a register setting outside of the registers listed in SPI init is affecting the MISO input.
解決済! 解決策の投稿を見る。
Hi Dustin
for usage CSI0_DAT10 as ECSPI2 MISO one also needs
to set daisy chain with register IOMUXC_ECSPI2_IPP_IND_MISO_SELECT_INPUT,
described in sect.43.3.492 IOMUXC_ECSPI2_IPP_IND_MISO_SELECT_INPUT
(IOMUXC_ECSPI2_IPP_IND_MISO_SELECT_INPUT) i.MX53 Reference Manual (rev.2.1 6/2012)
http://www.freescale.com/files/32bit/doc/ref_manual/iMX53RM.pdf
for spi test codes one can look at i.MX53 OBDS on
Lab and Test Software (2)
i.MX53 Quick Start Board|Freescale
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Dustin
for usage CSI0_DAT10 as ECSPI2 MISO one also needs
to set daisy chain with register IOMUXC_ECSPI2_IPP_IND_MISO_SELECT_INPUT,
described in sect.43.3.492 IOMUXC_ECSPI2_IPP_IND_MISO_SELECT_INPUT
(IOMUXC_ECSPI2_IPP_IND_MISO_SELECT_INPUT) i.MX53 Reference Manual (rev.2.1 6/2012)
http://www.freescale.com/files/32bit/doc/ref_manual/iMX53RM.pdf
for spi test codes one can look at i.MX53 OBDS on
Lab and Test Software (2)
i.MX53 Quick Start Board|Freescale
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Ah, so there was another register I was missing. Thanks. That gets my application receiving SPI to the ECSPI2_RXDATA buffer all by itself. However, the data received is still bad.
The numbers in RXDATA are wrong. It appears that the MISO input is reading any number of 0s, but only the first low to high transition. Afterward, it only reads 1s and misses any high to low transitions. Examples: 00,55,AA becomes 00,7F,FF, and 00,00,30 becomes 00,00,3F.
Would anything in pad control do that?
I do not think that pad control can influence on that,
suggest to look at spi examples in obds
Best regards
igor
Thanks for the reply. I looked at the imx_ecspi.c file from the On-Board Diagnostic Suite. Following the spi transfer example and keeping my working init function, I only see 0x00 in the receive buffer.
The difference in my code vs the example is that I am sending a single byte and reading the rx buffer prior to sending the next byte. Not using the FIFO. and it works, but returns sticky bit data instead of the expected values. Makes me think hw failure.
I am going to stop troubleshooting this for a week or two. Get some new hardware in and try again.
Example that uses FIFO from imx_ecspi.c converted to use the registers from Freescale/iomcimx535.h:
int imx_ecspi_xfer(unsigned char *tx_buf, int burst_bytes)
{
unsigned int *p_buf;
int len, ret_val = 0;
ECSPI2_CONREG_bit.EN = 1; /* enable spi */
// move data to the tx fifo
for (p_buf = (unsigned int *)tx_buf, len = burst_bytes; len > 0; p_buf++, len -= 4) {
ECSPI2_TXDATA = *p_buf;
}
ECSPI2_CONREG_bit.XCH = 1;// set xch bit
// poll on the TC bit (transfer complete)
while (ECSPI2_STATREG_bit.TC == 0);
// clear the TC bit
ECSPI2_STATREG_bit.TC = 1;
// move data in the rx buf
for (p_buf = (unsigned int *)tx_buf, len = burst_bytes; len > 0; p_buf++, len -= 4) {
*p_buf = ECSPI2_RXDATA;
}
return ret_val;
}