3

I am trying to initialize SDCard using SPI on STM32F303 when I sent CMD0 command which is (0x40 0x00 0x00 0x00 0x00 0x95) and I tried to have a look of the signal that is coming from MOSI on the oscilloscope I saw different signal as shown below. Please note that SPI speed is 281.25kBits/s. any help would be appreciated.

Here is Part of the code I am using to test this output from MOSI

uint8_t cmd0[6]={0x40,0x00,0x00,0x00,0x00,0x95};
FATFS_CS_HIGH;
HAL_SPI_Transmit(&hspi1, (uint8_t*)0xff, 1, 10);
    for(int i=0;i<10;i++)
  {
    HAL_SPI_Transmit(&hspi1, (uint8_t*)0xff, 1, 10);
   }

  FATFS_CS_LOW;

while(1){

      HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[0], 1, 10);

      HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[1], 1, 10);
      HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[2], 1, 10);
      HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[3], 1,10);
      HAL_SPI_Transmit(&hspi1,(uint8_t *) cmd0[4], 1, 10);
      HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[5], 1, 10);

    }

Now I am sending the correct command and I can see it on the scope.However, I don't get 0x01 response(I keep getting 0xff) from SDcard(SanDisk Ultra 40MB/s ...16GB) I am using the following code:

FATFS_CS_HIGH;
for (int i = 0; i < 10; i++) {
    HAL_SPI_Transmit(&hspi1, &dumb, 1, 10);
    while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
}

FATFS_CS_LOW;

HAL_SPI_Transmit(&hspi1, cmd0, 6, 10);
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

for (int i = 0; i < 10; i++) {
    HAL_SPI_Transmit(&hspi1, &dumb, 1, 10);
    while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
}
HAL_SPI_Receive(&hspi1, &c, 1, 10);
Bence Kaulics
  • 7,066
  • 7
  • 33
  • 63

1 Answers1

5

You do not wait the end of the SPI transfers before initiating the next one. You also should not send a buffer byte by byte, you can send the whole buffer in one call.

HAL_SPI_Transmit(&hspi1, cmd0, 6, 10);
while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

This part of your code just sends rubbish, apart from the problem that you do not wait before sending next byte:

HAL_SPI_Transmit(&hspi1, (uint8_t*)0xff, 1, 10);

for(int i=0;i<10;i++)
{
    HAL_SPI_Transmit(&hspi1, (uint8_t*)0xff, 1, 10);
}

The second parameter is a pointer to the databuffer. Your code won't send 0xff but some rubbish located at the 0xff memory address.

To send 0xff do the following:

uint8_t value = 0xff
HAL_SPI_Transmit(&hspi1, &value, 1, 10);
while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

Update:

Also lines like this:

HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[0], 1, 10);

send rubbish data as well.

This cmd0[0] will return the first element of the array (the data) which is 0x40, then you cast it to uint8_t*, and pass it to the HAL_SPI_Transmit function as the pointer to the data buffer. So the actual data that will be sent is some random value at 0x40 memory location.

The address of a certain byte in your array is &cmd[0] for example. Note the & operator which returns the address. The correct call is:

HAL_SPI_Transmit(&hspi1, &cmd0[0], 1, 10);
while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

So I suggest again to send the whole array in one call as I showed it above.

Bence Kaulics
  • 7,066
  • 7
  • 33
  • 63
  • _Your code won't send 0xff but some rubbish located at the 0xff memory address_ - this main problem. – imbearr Nov 25 '16 at 20:43
  • Thank you very much Bence Kaulics. I have tried intensively to get it worked but with no success. I thought "HAL_SPI_Transmit" takes care of making sure that a byte is sent completely. Would you recommend any good reference to work with stm32 family? Thanks again. – Abdelraheem Alkuor Nov 28 '16 at 06:18
  • There is a downloadable zip at the bottom of the page: http://www.st.com/en/embedded-software/stm32cubef3.html which holds STM32F3 HAL examples. – Bence Kaulics Nov 28 '16 at 09:25
  • Kindly look at my edited question Bence Kaulics. Thank you. – Abdelraheem Alkuor Nov 30 '16 at 05:43
  • @AbdelraheemAlkuor I will try to have a look on it sometime. – Bence Kaulics Nov 30 '16 at 09:48