cancel
Showing results for 
Search instead for 
Did you mean: 

Getting extra 0 valued bytes on STM32F303VCT6 SPI3 MOSI Line

davidharrison9
Associate II
Posted on January 11, 2015 at 23:22

Hi, I am configuring SPI3 on STM32F303VCT6 to drive an SD card. I am getting an extra 0 valued byte after each wanted transmitted byte on the MOSI line. I have tried everything and can't get rid of them. The data width is set to 8 bits.

My SPI initialisation code is here :

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);

   SPI_I2S_DeInit(SPI3);

   SPI_InitTypeDef SPI_InitStructure;

   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;  // Initially very slow - 281.250 KHz

   SPI_InitStructure.SPI_Mode              = SPI_Mode_Master;

   SPI_InitStructure.SPI_Direction        = SPI_Direction_2Lines_FullDuplex;

   SPI_InitStructure.SPI_CPOL               = SPI_CPOL_Low;

   SPI_InitStructure.SPI_CPHA               = SPI_CPHA_1Edge;

   SPI_InitStructure.SPI_DataSize         = SPI_DataSize_8b;

   SPI_InitStructure.SPI_FirstBit            = SPI_FirstBit_MSB;

   SPI_InitStructure.SPI_NSS                 = SPI_NSS_Soft;

   SPI_Init(SPI3, &SPI_InitStructure);

   SPI_CalculateCRC(SPI3, DISABLE);

   SPI_Cmd(SPI3, ENABLE);

  while (1)

   {

      SelectSDCard();

      SpiPutGetByte(0xA1);

      SpiPutGetByte(0xB2);

      SpiPutGetByte(0xC3);

      SpiPutGetByte(0xD4);

      DeSelectSDCard();

      core_timer_delay_us(20);

      BlinkLED(REDLEDOutPin, LED_FAST_FLASH);

   }

static U8 SpiPutGetByte(U8 data)

{

   SPI3->DR = (U8)data;

   // Wait until data has been transmitted

   while (!(SPI3->SR & SPI_I2S_FLAG_TXE));

   // Wait for any received data to be complete

   while (!(SPI3->SR & SPI_I2S_FLAG_RXNE));

   // Make sure the SPI is not busy

   while (SPI3->SR & SPI_I2S_FLAG_BSY);

    return (U8)SPI3->DR;

}

GPIOs etc. have already been set correctly elsewhere.

For test purposes, I have got a simple loop that is transmitting four bytes - 0xA1, 0xB2, 0xC3 and 0xD4 followed by a 20uS pause, then repeating.

You can see in the attached screen shot that the lower green traces are behaving correctly - they are from a working PIC32 implementation transmitting the same data. Whereas the top traces are not working - you can clearly see the additional 0 value bytes after every wanted transmitted byte.

Any help would be appreciated. Thanks.
1 REPLY 1
davidharrison9
Associate II
Posted on January 12, 2015 at 20:15

So I finally figured out what was wrong. it turns out that since the SPI3->DR register is 16 bits if you write to in directly, as in : SPI3->DR = data; you will always get a 16 bit data transfer, regardless of the datasize setting.

I found the SPI_SendData8 and SPI_ReceiveData8 functions in the STD periphs library stm32f30x_spi.c file which access the SPI Data Register indirectly by dereferencing its address. I modified my read/write functions as follows :

static

const

U32

spi3DR = (

U32

)SPI3 + 0x0C;

 

static

U8

SpiPutGetByte(

U8

data)

 

{

 

  

// Wait until DR register is empty

 

   while (!(SPI3->SR & SPI_I2S_FLAG_TXE));

   // Send a Byte through the SPI peripheral

 

   *(volatile U8 *)spi3DR = data;

   // Wait for any received data to be complete

 

   while (!(SPI3->SR & SPI_I2S_FLAG_RXNE));

   // Return the Byte read from the SPI bus

 

   return *(volatile U8 *)spi3DR;

 

}

Talk about obscure!! This not at all clear from the datasheet!

In addition you have to set the Rx FIFO threshold to 1/4 by using

// Configure the RX FIFO Threshold

// This is necessary for 8bit data transfers!!

SPI_RxFIFOThresholdConfig(SPI3, SPI_RxFIFOThreshold_QF); in the SPI initialisation code.

Hi, I am configuring SPI3 on STM32F303VCT6 to drive an SD card. I am getting an extra 0 valued byte after each wanted transmitted byte on the MOSI line. I have tried everything and can't get rid of them. The data width is set to 8 bits.

My SPI initialisation code is here :

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);

   SPI_I2S_DeInit(SPI3);

   SPI_InitTypeDef SPI_InitStructure;

   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;  // Initially very slow - 281.250 KHz

   SPI_InitStructure.SPI_Mode              = SPI_Mode_Master;

   SPI_InitStructure.SPI_Direction        = SPI_Direction_2Lines_FullDuplex;

   SPI_InitStructure.SPI_CPOL               = SPI_CPOL_Low;

   SPI_InitStructure.SPI_CPHA               = SPI_CPHA_1Edge;

   SPI_InitStructure.SPI_DataSize         = SPI_DataSize_8b;

   SPI_InitStructure.SPI_FirstBit            = SPI_FirstBit_MSB;

   SPI_InitStructure.SPI_NSS                 = SPI_NSS_Soft;

   SPI_Init(SPI3, &SPI_InitStructure);

   SPI_CalculateCRC(SPI3, DISABLE);

   SPI_Cmd(SPI3, ENABLE);

  while (1)

   {

      SelectSDCard();

      SpiPutGetByte(0xA1);

      SpiPutGetByte(0xB2);

      SpiPutGetByte(0xC3);

      SpiPutGetByte(0xD4);

      DeSelectSDCard();

      core_timer_delay_us(20);

      BlinkLED(REDLEDOutPin, LED_FAST_FLASH);

   }

static U8 SpiPutGetByte(U8 data)

{

   SPI3->DR = (U8)data;

   // Wait until data has been transmitted

   while (!(SPI3->SR & SPI_I2S_FLAG_TXE));

   // Wait for any received data to be complete

   while (!(SPI3->SR & SPI_I2S_FLAG_RXNE));

   // Make sure the SPI is not busy

   while (SPI3->SR & SPI_I2S_FLAG_BSY);

    return (U8)SPI3->DR;

}

GPIOs etc. have already been set correctly elsewhere.

For test purposes, I have got a simple loop that is transmitting four bytes - 0xA1, 0xB2, 0xC3 and 0xD4 followed by a 20uS pause, then repeating.

You can see in the attached screen shot that the lower green traces are behaving correctly - they are from a working PIC32 implementation transmitting the same data. Whereas the top traces are not working - you can clearly see the additional 0 value bytes after every wanted transmitted byte.

Any help would be appreciated. Thanks.