2015-01-11 02:22 PM
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.2015-01-12 11:15 AM
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.