cancel
Showing results for 
Search instead for 
Did you mean: 

SPI1 In master mode receives ZERO no matter what

wouter
Associate II
Posted on December 09, 2009 at 08:03

SPI1 In master mode receives ZERO no matter what

12 REPLIES 12
wouter
Associate II
Posted on May 17, 2011 at 13:12

Hi we have been trying to get the STM32F103RE SPI1 working with the NANOPAN5375. After trying different methods for almost a week now we weren't able to get anything back besides a ZERO. As soon as something gets written out of the SPI1, the RXNE bit gets set (which should only be set when we receive something.)

If I read out the data it returns zero. The SPI write to the radio is not asking to send data. So Ideally the RXNE bit must not be set. This is what confuses us. We cannot read or write to the radio. I am using NSS software and configure the NSS as a regular GPIO. Before we connected this radio to an ATMEL128 and it worked perfectly. Now that we made a switch to the ST we have had a lot of issues with the SPI and I2C.

Code:

#include

void RCC_Configuration(void);

void GPIO_Configuration(void);

void SPI_Inittest(void);

void SPI_Writetest(void);

ErrorStatus HSEStartUpStatus;

GPIO_InitTypeDef GPIO_InitStructure;

SPI_InitTypeDef SPI_InitStructure;

int main()

{

RCC_Configuration(); //Intialize all the clocks

GPIO_Configuration(); //Initialize the GPIO

SPI_Inittest();

while(1)

{

SPI_Writetest(); //Write to Radio

}

}

void RCC_Configuration(void)

{

RCC_DeInit();

/* Enable HSE */

RCC_HSEConfig(RCC_HSE_ON);

/* Wait till HSE is ready */

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if (HSEStartUpStatus == SUCCESS)

{

/* Enable Prefetch Buffer */

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

/* Flash 2 wait state */

FLASH_SetLatency(FLASH_Latency_2);

/* HCLK = SYSCLK */

RCC_HCLKConfig(RCC_SYSCLK_Div1);

/* PCLK2 = HCLK */

RCC_PCLK2Config(RCC_HCLK_Div16);

/* PCLK1 = HCLK/2 */

RCC_PCLK1Config(RCC_HCLK_Div2);

/* PLLCLK = 8MHz * 9 = 72 MHz */

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

/* Enable PLL */

RCC_PLLCmd(ENABLE);

/* Wait till PLL is ready */

while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

{}

/* Select PLL as system clock source */

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

/* Wait till PLL is used as system clock source */

while (RCC_GetSYSCLKSource() != 0x08)

{}

}

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

}

void GPIO_Configuration(void)

{

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | //Configure PC2..PC7 as outputs push-pull, max speed 50 MHz

GPIO_Pin_4 | GPIO_Pin_5 |

GPIO_Pin_6 | GPIO_Pin_7 ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure);

}

void SPI_Inittest(void)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB | RCC_APB2Periph_SPI1, ENABLE);

// Configure SPI1 pins: SCK, MISO and MOSI

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 |GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

// Configure I/O for Chip select

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_SetBits(GPIOA,GPIO_Pin_4); //NSS High Initially

// SPI1 configuration

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;

SPI_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(SPI1, &SPI_InitStructure);

// Enable SPI1

SPI_Cmd(SPI1, ENABLE);

}

void SPI_Writetest()

{

GPIO_ResetBits(GPIOA,GPIO_Pin_4); //NSS puuled low to start writing to radio

SPI_I2S_SendData(SPI1,0x81);

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

SPI_I2S_SendData(SPI1,0x00);

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

SPI_I2S_SendData(SPI1,0x42);

GPIO_SetBits(GPIOA,GPIO_Pin_4);

}

[ This message was edited by: wouter.vanaken on 18-05-2009 22:22 ]

[ This message was edited by: wouter.vanaken on 18-05-2009 23:35 ]

16-32micros
Associate III
Posted on May 17, 2011 at 13:12

Hi wouter,

Please try to check your Voltage Level Translator ( TXB0106), I think that VCCB and VCCA are inverted , VCCA should be <= VCCB and in your case it is not :

http://www.ti.com/lit/gpn/txb0106

Please let me know if i have missed something 🙂

Cheers,

STOne-32.

[ This message was edited by: STOne-32 on 18-05-2009 22:34 ]

wouter
Associate II
Posted on May 17, 2011 at 13:12

Uhm my VccA is 2.5V and my VccB is 3.3V So i'm pretty sure that VCCA is <= VCCB :-D. You got me really confused for a second!

Greetz,

Wova

[ This message was edited by: wouter.vanaken on 18-05-2009 23:31 ]

16-32micros
Associate III
Posted on May 17, 2011 at 13:12

Hi wouter,

I though VCC2_5 is VCC2 = 5volts for Radio and VCC3_3 : VCC3 = 3 volts for STM32 :(

I have some comments on your design :

1) STM32 can run with VDD = 2.5Volts => level shifter are not useful and you can remove them.

2) Looking at ''nanoPAN 5375 Module pin description'', I have noticed that pin 7 :SPITXD is SPI data output from the module to the microcontroller. This pin is open-drain as default. This pin must have a pull-up to Vcc because the pin is driven only when a logical 0 is sent from nanoLOC to the SPI marker. Reconnected value: 100 kΩ. This pin can be programmed as push-pull output.

=> I believe this is the mistake 🙂

Hope this can help you,

Cheers,

STOne-32

[ This message was edited by: STOne-32 on 19-05-2009 20:13 ]

wouter
Associate II
Posted on May 17, 2011 at 13:12

Hi,

I only have send you a part of the design but we have some other stuff also running on the board that require a 3.3V and since we had more devices that require 3.3V it was better to run on 3.3V because then we don't need level translators for all those :-D. I scoped out everything before and after the level translator and it follows the input nicely so I really don't think this is the issue. I replaced the 1Mohm with a 100Kohms but the result is still the same however when we start playing with the Power on reset pin from the NANOPAN that now is connected to PB0 in stead of DIIO0 we sometimes read out 0xFF. but as soon as want to read this out on the scope the MISO drops again. I know it might sound a bit confusing but that is what we all are right now :-? .

Thank you for the replies so far.

Greetz!

Wouter

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

Wonder if SPI1 is somehow being disabled by other options you've selected? Suggest that you review/check. Here is a technique we've used which has always worked:

a) temporarily replace the radio SPI connection with the simplest SPI device you have/can obtain. (an eeprom seems simplest to us) Confirm that you can both write to and read from the simpler eeprom.

b) usually you must send some command to the SPI device before it will ''answer back.'' Thus it may be that you have ''transmit'' as well as ''receive'' issues with SPI1. Can you store the ''working'' data transactions - both send & receive - using your earlier Atmel micro for a reference test? Once you have that data captured you can systematically compare the STM32's signals with those. Insure that you are transmitting correctly.

c) perhaps there is a ''turn-around'' time issue with the radio - STM32? Again observe what worked - see how your STM32 transaction compares.

We read here - again & again - about ''failed'' SPI, I2C, and Uart communications. And in most cases users have ''not'' made a ''simple - confirming initial test'' - so that they can proceed methodically.

In summary - your case seems strange as it appears that you have a ''known good'' SPI test device (your radio chip). This leads one to believe that you simply need to compare the signal history ''when working'' with that obtained ''when failed.'' Good luck.

wouter
Associate II
Posted on May 17, 2011 at 13:12

Hi,

We bring SPI3 out to ext header pins and connected a radio directly to this one. Brought down the voltage to 2.5V so we could leave the level translator out. Didn't change anything in the code just changed the interface to SPI3 and it works. we remapped SPI1 to SPI3 and this worked to. After that we connected an M25P80 spi flash to SPI1 and this worked too. However we know that this level translator works in our other design I think you are right saying that there might be a turnaround issue.

We had to lower the pull-up value from a recommende 100k to 10k because otherwise with the rise time it doesn't reach 2.5V Not even when running on 1MHz. Any comments about this?

So we still have a far way to go but at least we got the radio working with the ST which is nice to end the week.

Thank you for the replies so far...

Greetz,

Wouter

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

This is good news - we've jumped the hurdle of, ''maximum randomness.''

Since you can ''talk'' STM-radio via SPI3 your set-up & code is most likely correct. And since you talked between spi flash & STM32 it appears you have not disabled SPI1. We like the way you are proceeding - your building evidence/understanding systematically.

I would ''capture'' the most basic SPI transaction via SPI3 and your radio. (on a storage scope or logic analyzer) Then revert to SPI1 and see ''exactly'' what's different. As you report that you ''only'' see ''zeros'' you may have to gradually decrease the pull up Rs. Perhaps the SPI1 MISO pin is ''somehow'' loaded or otherwise degrading the radio's signal?

Please slow the SPI1 speed even more - you have to give the interface every chance to succeed - then - one by one - we can determine the real cause & issue. Your on the right track - bet you solve this shortly...

wouter
Associate II
Posted on May 17, 2011 at 13:12

Hi there!

So we captured a basic transaction on spi3 and then compared it to the one on SPI1 After the level translator we still see the same signal, nicely shaped but just on a lower level. When we measure the MISO on the NANOPAN side it is still nicely shaped but the amplitude is not high enough to drive the level translator output in high or low state so I went back to the datasheet where i ran into this...

TXB0106

''Input Driver RequirementsFor proper operation, the device driving

the data I/Os of the TXB0106 must have drive strength of at least ±2 mA.''

NANOPAN

''SpiTxD: Maximum output current 2mA.''

So the reason it was working before was because we were lucky I guess... :( The scenario we use it in right now by driving it on its minimum driver input current will not guarantee us a reliable operation. I'll try changing the level translator to the SN74AVC4T245. I'm planning on using 2. 1 for inputs and 1 for outputs. That will give me the opportunity to bring out some more pins from the radio.

I thank the both of you for all the comments because it sure was a big help to us in finding the source of the problem.

Greetz,

Wouter