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.

AM3517 MSPI READ

Other Parts Discussed in Thread: AM3517, SYSCONFIG

Hello,

I am using AM35x-OMAP35x-PSP-SDK-03.00.01.06 sdk with my AM3517 EVM board. Now I connect the MSPI1.0 to a eeprom AT25640.

I add the following into the boot board file(board-am3517.c)and register a spi device.

static struct spi_eeprom at25640a = {

.byte_len = SZ_64K ,

.name = "at25640a",

.page_size = 32,

.flags = EE_ADDR2,

};

static struct spi_board_info am3517_evm_spi_info[] __initconst = {

{

.modalias = "at25",

.platform_data = &at25640a,

.max_speed_hz = 50 * 1000, /* at 3v3 */

.bus_num = 1,

. chip_select = 0,

.mode = SPI_MODE_0,

},

}

static void __init am3517_evm_init(void)

{

......

spi_register_board_info(am3517_evm_spi_info, ARRAY_SIZE(am3517_evm_spi_info));

......

 

}.

But now there is a problem.When I read the eeprom using the AT25 driver the spi1.0 , the incorrect will be return.

eg.I have writen 0x01 to eeprom but only ox00 will be return.

I checked with Oscilloscope,and the CS,SCLK, SOMI,SIMO are have correct signal.

When read the eeprom, there is a single that the 0x01 is on the SOMI pin but the AM3517 RX register only has the incorrectly data 0x00.

Can someone tell me what's the problem and how to solve it?

note:I use the spi1 module and the chip selected pin 0


Thanks,

Shepherd


 

  • Shepherd

    Have you checked the pinmux configuration for the SPI signals? This are usually the source of Linux SPI driver problems.

    In particular check the CLK and MISO signals. Check that both of these have the input enabled. The MISO needs the input enabled for obvious reasons. The CLK needs the input enabled in order to drive the clock to the SPI reciever circuit.

      Paul

  • Hi Paul,
     
    I have mux the pin and add the following codes into the array named board_mux in board level port file(board-am3517evm.c).
    But the result is also incorrect  and  the 0x00 is return in RX Register.
    #ifdef CONFIG_OMAP_MUX
    static struct omap_board_mux board_mux[] __initdata = {
     /* USB OTG DRVVBUS offset = 0x212 */
     OMAP3_MUX(CHASSIS_DMAREQ3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
     OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
     OMAP3_MUX(GPMC_NCS4, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLDOWN),
    #if 1
     OMAP3_MUX(MCSPI1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
     OMAP3_MUX(MCSPI1_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
     OMAP3_MUX(MCSPI1_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
     OMAP3_MUX(MCSPI1_CS0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
    #endif
     { .reg_offset = OMAP_MUX_TERMINATOR },
    };
    #else
    #define board_mux NULL
    #endif
     
    the array is used by the omap3_mux_init function as the first argument and the omap3_mux_init function  is called by the board init function \
    am3517_evm_init , I think i have mux the spi spin signal.
    So Is there any other reason case the RX register the values incorrect?
    Thanks,
    Shepherd

  • Shepherd

    I recently saw a case where the pinmux is reconfigured after booting in to Linux resulting in similar issues. Therefore it is still possible that the pinmux is incorrect. Could you check the pinmux value from your code? If that still looks ok then a dump of the SPI register settings would be useful to ensure that he interface is configured correctly.

      Paul

  • Hi Paul,

    Please see PINMUX:

    CONTROL_PADCONF_MCSPI1_CLK = 0

    CONTROL_PADCONF_MCSPI1_SOMI = 100

    are they correct? I read it from at25_ee_read function in drivers/misc/eeprom.

     

    Thanks,

    Rain

  • Rain

    MCSPI1_SOMI = 0x100 is correct. Bit 8 enables the input on the SOMI pin.

    MCSPI1_CLK = 0x0 is not correct. The input needs to be enabed on the clock pin so that the clock can drive the receiver.
    The correct value should be 0x100. Bit 8 enables the input for the clock.  

      Paul

  • Hi Paul,

    PaulM said:

    MCSPI1_CLK = 0x0 is not correct. The input needs to be enabed on the clock pin so that the clock can drive the receiver. 

    The correct value should be 0x100. Bit 8 enables the input for the clock.  

      Paul

    I change MCSPI1_CLK to 0x100, the result is the same, all read data are 0.

    I found one problem, please see below two pictures.

    The first picture is cut from AM3517 datasheet, the second is from at25640a.

    AM3517 SPI is working under 3.3v mode 0, it said that the MAX SM5 is 6 ns, but you can see the second picture, the MIN tcss is 50ns. They mismatch much!

    Does this the reason why I can't get the data? 

    If so, use GPIO to emulate SPI? or how can I config the AM3517 to use 1.8v mode?

    Thanks,

    Rain

  • Rain

    The datasheet appears to have a typo as it should have a similar formula for “A” under the max value.

     

    The delay between CS and the first/last edge of the SPI clock is programmable using the MCSPI_CH1CONF:TCS bits [26:25].

     

    0x0: 0.5 clock cycle [default]

    0x1: 1.5 clock cycles

    0x2: 2.5 clock cycles

    0x3: 3.5 clock cycles

     

    By changing the TCS value you can add up to 3 clock cycles. I don’t know what your clock period is but, even if it were the minimum 20.8ns, you could add over 60ns to the delay between CS and the first clock edge.

     

    Another alternative would to manually control the CS signal. Bit banging is also an option but I don’t recommend it in this case when there are better alternatives available.

     

    You should also be able to see what data will be captured by the SPI receiver by looking at the somi signal at each capture clock edge.

     

    In addition, you can check the reception of data by configuring the SPI to loopback the transmitted data to the receiver. This can be done by enabling the input on spi1_simo and selecting it as input (MCSPI_CH1CONF:IS, bit 18 = 0x1).  I’ve not personally tried this but doing this should help determine where your issue is located.

    You can configure the AM3517 to be 1.8v mode by applying 1.8v to the VDDSHV pins. Please note that this will change all the i/o pins that use the VDDHS power domain (most of them). A full list can be found in  section 2.2 of the current data sheet

      Paul

     

  • Hi Paul,

    After I set the clocks, I still got 0, but I can see the data 0x101 what's I exact write to eeprom, please see the picture from OSC. So I believe, the data indeed come out from the eeprom, and from the OSC, the data seem right. The frequency is 6MHz, so from the OSC, the clock is working properly. Yellow: SOMI signal, Blue: SCLK signal.

    I dump all the register values before I receive the data, please see:

     

    Before receive ...

    OMAP2_MCSPI_REVISION: 0x21

    OMAP2_MCSPI_SYSCONFIG: 0x15

    OMAP2_MCSPI_SYSSTATUS: 0x1

    OMAP2_MCSPI_IRQSTATUS: 0x7

    OMAP2_MCSPI_IRQENABLE: 0x0

    OMAP2_MCSPI_WAKEUPENABLE: 0x1

    OMAP2_MCSPI_SYST: 0x0

    OMAP2_MCSPI_MODULCTRL: 0x1

    OMAP2_MCSPI_CHCONF0: 0x1113cc

    OMAP2_MCSPI_CHSTAT0: 0x7

    OMAP2_MCSPI_CHCTRL0: 0x1

    OMAP2_MCSPI_TX0: 0x0

    OMAP2_MCSPI_RX0: 0x0

    you can see OMAP2_MCSPI_CHSTAT0: 0x7, data indeed received, but all 0.

    PaulM said:
     
    In addition, you can check the reception of data by configuring the SPI to loopback the transmitted data to the receiver. This can be done by enabling the input on spi1_simo and selecting it as input (MCSPI_CH1CONF:IS, bit 18 = 0x1).  I’ve not personally tried this but doing this should help determine where your issue is located.

    Paul

    please see the result:

    OMAP2_MCSPI_REVISION: 0x21

    OMAP2_MCSPI_SYSCONFIG: 0x15

    OMAP2_MCSPI_SYSSTATUS: 0x1

    OMAP2_MCSPI_IRQSTATUS: 0x7

    OMAP2_MCSPI_IRQENABLE: 0x0

    OMAP2_MCSPI_WAKEUPENABLE: 0x1

    OMAP2_MCSPI_SYST: 0x0

    OMAP2_MCSPI_MODULCTRL: 0x1

    OMAP2_MCSPI_CHCONF0: 0x1513cc

    OMAP2_MCSPI_CHSTAT0: 0x7

    OMAP2_MCSPI_CHCTRL0: 0x1

    OMAP2_MCSPI_TX0: 0x5

    OMAP2_MCSPI_RX0: 0x505

    I write 0x5, got 0x505. I use 8 bit mode, so I think the last date 5 is what we need.

     

  • Rain

    I don't see anything wrong with the SPI configuration.  Switching the input and seeing what was written proves that the setup is correct.

    The scope snapshot also shows the correct data on somi which would be captured by the receiver on the rising edge of the clock.

    Can you check/dump the pinmux settings just before you receive data as you have done the spi register settings? I know that you have present these earlier but I would like to rule out that they have not been changed prior to the actual use of the spi bus.

    Also, when you are communicating with the eeprom I assume that you are flushing out the junk data received while sending the instruction(s)?  There will be one word received for every word transmitted.

      Paul

  • PaulM said:

    Rain

    Can you check/dump the pinmux settings just before you receive data as you have done the spi register settings? I know that you have present these earlier but I would like to rule out that they have not been changed prior to the actual use of the spi bus.

      Paul

     

    Before rx ...

    OMAP2_MCSPI_REVISION: 0x21

    OMAP2_MCSPI_SYSCONFIG: 0x15

    OMAP2_MCSPI_SYSSTATUS: 0x1

    OMAP2_MCSPI_IRQSTATUS: 0x7

    OMAP2_MCSPI_IRQENABLE: 0x0

    OMAP2_MCSPI_WAKEUPENABLE: 0x1

    OMAP2_MCSPI_SYST: 0x0

    OMAP2_MCSPI_MODULCTRL: 0x1

    OMAP2_MCSPI_CHCONF0: 0x1113cc

    OMAP2_MCSPI_CHSTAT0: 0x7

    OMAP2_MCSPI_CHCTRL0: 0x1

    OMAP2_MCSPI_TX0: 0x0

    OMAP2_MCSPI_RX0: 0x0

    CONTROL_PADCONF_MCSPI1_CLK = 100

    CONTROL_PADCONF_MCSPI1_SOMI = 118

    You can see, the values are right. I pull up the miso, if not, we get miso signal low voltage.

    PaulM said:

    Rain

    Also, when you are communicating with the eeprom I assume that you are flushing out the junk data received while sending the instruction(s)?  There will be one word received for every word transmitted.

      Paul

    I didn't change the read/write function, I use standard driver omap2_mcspi.c and at25.c. So I think there is no problem.

     

  • Rain

     

    Agreed, the SOMI pinmux looks correct.

    Can you post a scope capture of CLK and SOMI which includes the complete command and response (basically during the CS active period )?

     

    How many words to you send and how many words do you read? Of the words read, which one are you expecting to have the data?

     

    Thanks

     

      Paul

     

     

  • PaulM said:
    Can you post a scope capture of CLK and SOMI which includes the complete command and response (basically during the CS active period )?
     
     

     

    Maybe it's hard to do so, I'll try tomorrow.

     

    PaulM said:
     
    How many words to you send and how many words do you read? Of the words read, which one are you expecting to have the data?
     

    I send 4*1024 bytes and read 4*1024 bytes. I write all 5 to eeprom, and also want to read all 5 from eeprom. The picture I capture from the OSC looks like I got 5, but actually I read all 0.

     

    Thanks,

     

    Rain

  • Rain

    Let me re-phrase my question.How many SPI words to you send per read command and how many of the received words do you read.

    For example, you send a one byte read op_code (0x03) followed by a 2 byte address, followed by one dummy byte for every data word to be read from the eeprom.
    Your code will receive 3 "junk" bytes (one for the op_copde and 2 for the address) followed by valid byte for each data word read.

    Now, I would expect the first 3 bytes to be 0xFF since the eeprom SO pin is hi-z and you have a pullup on the enabled on the SOMI pin.  This is what I would to check with scope capture.  What is happening with CS between bytes?

    Also Have you checked for any error conditions such as an RX_OVERFLOW?

      Paul

     

  • Hi Paul,

    I can get the right data now. It's hardware issue, our AM3517 may be broken about SPI part. I change to use another AM3517 to test SPI driver, on this board, I can write and read right data.

    Thanks for your support, I  greatly appreciate!

    Rain

  • Rain

    I'm happy to help.

      Paul

  • Hi Paul,

    Sorry to bother you again, another question:

    Tough I can get the right data, but as my test about the read write speed, write speed is 1.98MBps, while read speed is 136MBps, I don't know why? is it normal?

    The clock frequency of SPI I configure is 6MHz

    Thanks,

    Rain

  • Hi Paul,

    Please see the omap2_mcspi_txrx_pio function in omap2_mcspi.c, I use PIO mode to read 2048 bytes data from eeprom. I followed to this function and this cycle, I found it read 2048 bytes at once. But I just saw *rx++ = __raw_readl(rx_reg); ,didn't see any write to the TX register, so how the am3517 to give the clock to eeprom to let eeprom send the data to RX register?

    if (word_len <= 8) {

    u8 *rx;

    const u8 *tx;


    rx = xfer->rx_buf;

    tx = xfer->tx_buf;


    do {

    c -= 1;

    if (tx != NULL) {

    if (mcspi_wait_for_reg_bit(chstat_reg,

    OMAP2_MCSPI_CHSTAT_TXS) < 0) {

    dev_dbg(&spi->dev, "TXS timed out\n");

    goto out;

    }

    printk(KERN_ALERT "write-%d %02x\n",

    word_len, *tx);

    #ifdef VERBOSE

    dev_dbg(&spi->dev, "write-%d %02x\n",

    word_len, *tx);

    #endif

    __raw_writel(*tx++, tx_reg);

    }

    if (rx != NULL) {

    if (mcspi_wait_for_reg_bit(chstat_reg,

    OMAP2_MCSPI_CHSTAT_RXS) < 0) {

    dev_dbg(&spi->dev, "RXS timed out\n");

    goto out;

    }

    /* prevent last RX_ONLY read from triggering

    * more word i/o: switch to rx+tx

    */

    if (c == 0 && tx == NULL)

    mcspi_write_chconf0(spi, l);

    *rx++ = __raw_readl(rx_reg);

    printk(KERN_ALERT "read-%d %02x\n",

    word_len, *(rx-1));

    #ifdef VERBOSE

    dev_dbg(&spi->dev, "read-%d %02x\n",

    word_len, *(rx - 1));

    #endif

    }

    } while (c);

     

    Rain

  • Hi Rain

    Rain Peng said:

    Tough I can get the right data, but as my test about the read write speed, write speed is 1.98MBps, while read speed is 136MBps, I don't know why? is it normal?

    The clock frequency of SPI I configure is 6MHz

    With a 6MHz clock the maximum throughput would be 6Mbps or 0.75MBps. However, only transfers with consecutive words (no cycling of CS) will see the maximum throughput but overall throughput will be less due to the CS assertion/de-assertion overhead.

    I'm not sure how you arrivied at the numbers you list.

    Rain Peng said:

    Please see the omap2_mcspi_txrx_pio function in omap2_mcspi.c, I use PIO mode to read 2048 bytes data from eeprom. I followed to this function and this cycle, I found it read 2048 bytes at once. But I just saw *rx++ = __raw_readl(rx_reg); ,didn't see any write to the TX register, so how the am3517 to give the clock to eeprom to let eeprom send the data to RX register?

    I'm not familiar with that function but when the SPI master is setup for transmit and receive, dummy bytes must be sent to the slave in order to receive valid data.  Different slaves have different requirements but in general that's how SPI works.

    For your EEPROM:  "After the CS line is pulled low to select a device, the READ op-code is transmitted via the SI line followed by the byte address to be read (A15 - A0, Refer to Table 6). Upon completion, any data on the SI line will be ignored." (taken from page 10 of datasheet). So for every word you want to read you need to send a dummy word. The following diagram was taken from the same datasheet (page 12). I've circled in red the dummy word sent to the EEPROM in order to read a word from the device. If you want to ready 2 words then 2 dummy words must be sent. To read X words you'll need to send X words. The EEPROM allows you to read the entire contents with one read opcode and therefore, in this case, you can actually read the contents at the maximum throughput once the opcode and address have been sent.

      Paul

     

  • HI Paul,

    Thanks for your reply.

    I found why the driver can read all the data while just dummy one byte to TX register.  In the document "AM35x ARM Microprocessor Technical Reference Manual" section 16.5.2.4, the driver uses Master Receive-Only Mode.

    But I still didn't find why the speed is so high, everything looks correct.

    When write, the driver check TXS bit in MCSPI_CHxSTAT, when read, the driver check RXS bit. I assume these bit status changed based on the clock. It shouldn't faster than the clock. 

    Best regards,

    Rain

  • Rain

    Right, in receive only mode it is necessary to kick-start the transfer by writing one dummy word to the TX register.

    I can't explain the high throughput numbers other than perhaps a math error? only one bit can be transmitted/received for every clock cycle so the maximum bit rate for your setup (6MHz clock) is 6Mbps.

    The TXS and RXS status bits change as the transmit (TXS) and receive (RXS) registers become full or empty. If the transmit register is full then the program must wait until it becomes empty before writing a new word. If the the receive register is full then  the program must read the word before a new word can be received. The exception to this is TURBO mode which will allow a second word to be received in the shift register even though the receive register is full.

      Paul