cancel
Showing results for 
Search instead for 
Did you mean: 

Bug in the silicon at SPI interface?!?

dschuethe9
Associate II
Posted on December 22, 2009 at 06:46

Bug in the silicon at SPI interface?!?

4 REPLIES 4
dschuethe9
Associate II
Posted on May 17, 2011 at 13:33

I have the dev. board STM32-P103 from Olimex with the STM32F103RB chip on it.

I want to connect the board via SPI to another MCU using the UEXT socket(where SPI1) is connected.

My problem is, that i can read data from the other MCU, as long as i am not loading data into the DR(SPI1) of stm32. The settings for SPI1 are the same as for the other MCU (CPOL and CPOH), the stm is programmed to slave mode with hardware nss. If i send data , i.e writing data to the DR register, there is something put out at the MISO, but totally wrong. E.g. if i write 0xaa to DR, i get on the scope either 0x3f(after reset for the first write) and 0xff for every following write. If I put 0x00 it is working as well as 0xff. But every other value is like a random output. Values to 0x04 are just 0x00(outputted).

I also tried it with the SPI2, but there I have the same problem. I thought that it has to do something with the SD cardreader which is connected to SPI2, but now with SPI1 the problem remains.

If I use the STM32 as Master, I can communicate with other SPI devices without problems. The failure only occures in slave mode. I also tried the software procedure which is written in the new reference manual, without any success. Also two other Engineers have had a look at this and can't find a solution. So maybe there is something wrong with the silicon. Especially with the shift register or something like that. because if i write 0x55 to the DR i get the right data out, but after 4cycles of SPI clocks and no new writing to the DR.

Have anyone tried to use the stm spi as slave? is it working?

CODE:

#include ''stm32f10x.h''

#include

void clock_init(void);

void spi_settings(void);

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* Configure SPI1 pins: SCK, MISO and MOSI */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configuration of NSS pin */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

GPIO_Init(GPIOA, &GPIO_InitStructure);

}

int main(void)

{

/*

@funtcion variables

*/

int repeat = 0, i=0;

u8 ReceivedData[4][4]={{0x01 , 0x02, 0x03 , 0x04},

{0x05 , 0x06, 0x07 , 0x08},

{0x09 , 0x10, 0x11 , 0x12},

{0x13 , 0x14, 0x15 , 0x16}};

u8 *pData;

clock_init();

//setting the peripheral clocks

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);

GPIO_Configuration();

spi_settings();

/*

@reading from MCU

*/

while(i

{

pData= &ReceivedData[i][0];

while(repeat < 4)

{

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

// Send SPI1 data

SPI_I2S_SendData(SPI1, 0x55);

//checks if the transmit buffer is empty

while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE));

//read data from receive register

pData[repeat] = SPI_I2S_ReceiveData(SPI1);

repeat++;

}

repeat=0;

i++;

}

i=0;

repeat=0;

for(i=0 ; i

{

for(repeat=0; repeat

printf(''%X'', ReceivedData[i][repeat]);

printf(''\n'');

}

return 0;

}

/*****************

@ clock_init

@ initializaton of the internal clocks to System Clock = 64MHz

*****************/

void clock_init(void)

{

RCC_DeInit(); //Resets the Clock registers to default reset state

RCC_HSICmd(ENABLE); //Enable the internal 8MHz Oscillator

while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY)== RESET); //wait till the HSI is ready

RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI); //using internal 8MHz RC as system clock

RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_14); //Maximum frequency using internal RC->56MHz

RCC_PLLCmd(ENABLE); //enable the pll clock

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)== RESET);

RCC_PCLK1Config(RCC_HCLK_Div2); //set APB1 Clock to AHB/2=28MHz APB1 max = 36MHz

RCC_PCLK2Config(RCC_HCLK_Div1); //set APB2 Clock to AHB = 56MHz

RCC_HCLKConfig(RCC_SYSCLK_Div1); //set the AHB clock = system clock

#ifdef EMB_FLASH

// 5. Init Embedded Flash

// Zero wait state, if 0 < HCLK 24 MHz

// One wait state, if 24 MHz < HCLK 56 MHz

// Two wait states, if 56 MHz < HCLK 72 MHz

// Flash wait state

FLASH_SetLatency(FLASH_Latency_2);

// Half cycle access

FLASH_HalfCycleAccessCmd(FLASH_HalfCycleAccess_Disable);

// Prefetch buffer

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

#endif // EMB_FLASH

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //using internal PLL = 56MHz

}

/*************

@ spi_settings

@ sets the spi peripheral to pins PB12...15, SPI1

************/

void spi_settings(void)

{

SPI_InitTypeDef SPI_InitStructure; //Struct for Init the SPI1

SPI_I2S_DeInit(SPI1); // Deinitialization of SPI1

/* setting the wanted setup for SPI1---------------------------------*/

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // Clock idle state - LOW

SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //data is captured on the 2nd edge

SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; // chip select done by hardware

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //Irrelevant in slave mode SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

/*-------------------------------------------------------------------*/

SPI_Init(SPI1, &SPI_InitStructure); //INIT the SPI Interface

SPI_SSOutputCmd(SPI1, DISABLE); // enable NSS pin as output

SPI_Cmd(SPI1, ENABLE); //Enables the SPI1 peripherial

}

tomas23
Associate II
Posted on May 17, 2011 at 13:33

What about different polarity and phase of the clock signal? Try on both sides the same, but all 4 settings. Btw. slave is tested and works well.

What's the master speed? Do you initialize ALL parameters of the init structure?

Enable the debug macro and check whether you don't stop on some assert, it's very useful approach.

A hint: HSI is a start-up oscillator, so until you disable it, it is always active and there is no need to start it again ;)

dschuethe9
Associate II
Posted on May 17, 2011 at 13:33

Hi, thanks for the answer.

But the problem still remains!

What I could fixed in the time is:

The STM32 slave can read signals from the master correctly, but only if the MISO(STM PIN) is not connected. Also the correct data is then driven out on MISO as I checked with a scope. But as far as I connect the MISO to the other Chip's MISO, the data on STM32 is read wrong and the send data is also wrong. If I send only a specific byte to the stm and send over the MISO an incrementing byte. I get everytime the same data from the stm32(which is wrong), independent from what I am sending to the stm32. AS I had a look at the shift register, it is used for sending and receiving simultanously, so I thought there is a timing problem and sometimes the data is shifted while data is receiving. But how is it then possible that MISO sends same data everytime? What is the conclusion between MISO and MOSI pin? I have no Idea what causes this failure, because it is working fine as long as MISO is not connected!

jj
Associate II
Posted on May 17, 2011 at 13:33

''I connect the MISO to the other Chip's MISO''

Suspect above is typo - shouldn't your Slave's MISO connect to the Master's MOSI? (slave out to master in)

Believe that you say that Slave's MISO pin behaves correctly when ''not'' connected to Master. Is there a voltage difference between the 2 MCUs? What happens if you have Slave's MISO drive ''just'' a 100K R tied to ground, a 47K, 22K, 10K etc?