SparkFun Forums 

Where electronics enthusiasts find answers.

Everything with the AmbiqSuite SDK tools and software are welcome here.
User avatar
By beanbox
#223860
Hi guys,
I'm having a strange problem here accessing a sd card. I have the same code running on a ATSAM device, so the code is fine. I'm trying to track down the issue a couple of days now. At the moment I'm anaylizing the SPI data with an oscilloscope capable of serial decoding.
It turns out that for the first couple of commands the SPI read is ok i.e. the MOSI is high during read. But at some point the situation changes and even when I when I execute a SPI read the Apollo3 seems to do a SPI write with value 0.
See the attached screenshot of the oscilloscope.
The low MOSI during read seems to confe the SD card because the following commands fail then.
Does anyone of you have a clue on that?

I have attached to screenshots of the oscilloscope. Both are captured by executing the code
Code: Select all
uint32_t SPI::R(uint8_t cs, uint8_t *data, uint32_t num_bytes) {

    uint32_t status = AM_HAL_STATUS_SUCCESS;

    memset(&m_xfer_rx,0,sizeof(m_xfer_rx));

    m_xfer_rx.ui32NumBytes = num_bytes;
    m_xfer_rx.eDirection = AM_HAL_IOM_RX;
    m_xfer_rx.pui32TxBuffer = NULL;
    m_xfer_rx.pui32RxBuffer = (uint32_t*)data;;
    status = am_hal_iom_blocking_transfer(m_iom_handle, &m_xfer_rx);
    if(status != AM_HAL_STATUS_SUCCESS)
    { 
      report(status); 
      return 0;
    }

    return m_xfer_rx.ui32NumBytes;
The first is as expected. The second seems to be a write. I have already debugged into the AmbiqSuite SDK and in both cases a read is constructed.
Code: Select all
ui32Cmd = build_cmd(ui32Cmd, ui32Dir,  ui32Cont, ui32Offset, ui32OffsetCnt, ui32Bytes);
with ui32Dir =1.
SDS00050.png
SDS00049.png
This is a real blocker for me. So please write me something, even if you don't have any ideas :)
You do not have the required permissions to view the files attached to this post.
By paulvha
#223891
interesting issue.. but no real idea.. only thoughts
  • Looking at the hal-code.. An AM_HAL_IOM_RX is only overturned to AM_HAL_IOM_TX if the number of bytes to read is zero. Could that happen in your code?
  • Not sure what board you have but is there maybe another SPI channel to try.
  • Could the MOSI GPIO be set low somewhere else in the code? E.g. like with CS?
  • Looking at the Artemis datasheet,in chapter 8.2 it talks about SPI flowcontrol, and one possibility is to use MOSI. I don't see anywhere in the code where that could be set (it is reset during init)
  • Is the TX FIFO not empty from a previous write or maybe still pending 0x0?
  • What is send just before it fails. Say the last bit was zero, is that being repeated with the next read (should not ..)
  • Any chance MOSI is pulled low by the SD ?
By paulvha
#223898
I have just connected my SPI analyzer on a BME280 while working in SPI and providing data in the sketch.

You clearly see on MOSI line the Artemis requests a register ( 0x8F, 0x8E, 0x91) and during each read the MOSI is set low, where the MISO provides the data.
You do not have the required permissions to view the files attached to this post.
User avatar
By robin_hodgson
#223950
What version of HAL/SDK are you using? If I remember right, Ambiq made some changes to SPI operation in regards to full-duplex/half-duplex as the versions got released.
User avatar
By robin_hodgson
#223952
How does correlate with the actual Ambiq SDK version? I think the latest Ambiq SDK is 2.5.1.
User avatar
By robin_hodgson
#223966
When describing an SPI read transfer that includes a register address write phase, section 8.8.4 of the data sheet says: "After the transfer of the last address bit (bit 0), the I2C/SPI Master stops driving the MOSI line". If that is literally true, then MOSI is floating while the IOM is reading. In section 8.8.6, the data sheet indicates that if the transfer is a raw read with no write of a register address to begin the transfer, then MOSI appears to be in a Hi-Z state for the whole duration. Maybe MOSI is just floating to 0 during your read. What if you added a 10K to 100K pullup on MOSI? If you still see a '0' on MOSI after adding the resistor, then someone has to be driving it.
User avatar
By robin_hodgson
#223968
I just ran an experiment. I have nothing connected to my IOM port, so the read transfers is going into oblivion. But that means that no one is possibly driving MOSI except the IOM itself. I did a single byte 'read register' transfer. The read register transfer begins with a write of the [fake] register address on MOSI, then the read is performed after the register address terminates. I see the register address go out, followed 8 more clocks while the IOM reads from the non-existent device. As you have observed, MOSI is '0' during the read operation. I then added a 20K pullup to MOSI, and it is still '0' during the read byte. When the transfer completes, MOSI goes high again. The only possible reason is that the IOM itself wants MOSI at '0' during the read operation.

If you really need MOSI at '1' during a read, maybe you need to do a full duplex read transfer where the outgoing TX buffer is all 0xFF bytes.
By paulvha
#223989
I think the later is the case.. you need to write a 0xff:

http://elm-chan.org/docs/mmc/mmc_e.html, command and response :
Because the data transfer is driven by serial clock generated by host controller, the host controller must continue to read data, send a 0xFF and get received byte, until a valid response is detected. The DI signal must be kept high during read transfer (send a 0xFF and get the received data).

I looked at the code for 2.0.5 (which is using Mbed) but in the end it is using the call spi_master_block_write() which handles works in
By paulvha
#223994
paulvha wrote: Sat Mar 13, 2021 3:42 am I think the later is the case.. you need to write a 0xff:

http://elm-chan.org/docs/mmc/mmc_e.html, command and response :
Because the data transfer is driven by serial clock generated by host controller, the host controller must continue to read data, send a 0xFF and get received byte, until a valid response is detected. The DI signal must be kept high during read transfer (send a 0xFF and get the received data).

I looked at the code for 2.0.5 (which is using Mbed) but in the end it is using the call spi_master_block_write() which handles works in
I did more work during the day and this is exactly what the Arduino SD-library does.. sending 0xff
 Topic permissions

You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

long long title how many chars? lets see 123 ok more? yes 60

We have created lots of YouTube videos just so you can achieve [...]

Another post test yes yes yes or no, maybe ni? :-/

The best flat phpBB theme around. Period. Fine craftmanship and [...]

Do you need a super MOD? Well here it is. chew on this

All you need is right here. Content tag, SEO, listing, Pizza and spaghetti [...]

Lasagna on me this time ok? I got plenty of cash

this should be fantastic. but what about links,images, bbcodes etc etc? [...]