cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Communication Issue

atkranz
Associate II
Posted on April 14, 2009 at 04:34

SPI Communication Issue

4 REPLIES 4
atkranz
Associate II
Posted on May 17, 2011 at 13:09

Hey guys,

I'm working on a project for school, and I'm trying to getting communication over the SPI to work right. I am trying to communicate with the LIS302 accelerometer in 4 pin SPI mode.

I can read any register just fine. The problem is that I can't read more than one. It always does whatever read command I gave it first. For example in the first example, I read from Cntrl_Reg1, then try reading from Cntrl_Reg2, and it returns the data in Cntrl_Reg1. I can tell it to do a sequential read as well, and then everytime I send a byte on the SPI, I get each sequential register. So the problem is that the accelerometer ignores new commands.

Anytime I reset, I can pick any register and read it, no problem, but once I read one, I can't read a different one.

I appreciate any tips or ideas.

Here is my initialization:

Code:

<BR> <BR>/************************************** <BR> * Start Accel. Config <BR> **************************************/ <BR> <BR> /* Accel. CS */ <BR> <BR> GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; <BR> GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; <BR> GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; <BR> GPIO_Init(GPIOB, &GPIO_InitStructure); <BR> <BR> <BR> /* Accel. MOSI */ <BR> GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; <BR> GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; <BR> GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; <BR> GPIO_Init(GPIOB, &GPIO_InitStructure); <BR> <BR> /* Accel. MISO */ <BR> GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; <BR> GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; <BR> GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; <BR> GPIO_Init(GPIOB, &GPIO_InitStructure); <BR> <BR> /* Accel. SCLK */ <BR> GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; <BR> GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; <BR> GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; <BR> GPIO_Init(GPIOB, &GPIO_InitStructure); <BR> <BR> /* SPI initialization stuff <BR> * Note: Accelerometer is attached to SPI2. <BR> * SPI is using slow clock (36MHz [APB1]) <BR> */ <BR> /* SPI: Master <BR> * 8 bit data mode <BR> * Serial clock steady state high <BR> * data capture on second edge <BR> * NSS controlled in software <BR> * baud prescaler = 64 (SPI clock should be ~ 5.6MHz) <BR> * MSB = first bit <BR> */ <BR> <BR> <BR> SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; <BR> SPI_InitStructure.SPI_Mode = SPI_Mode_Master; <BR> SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; <BR> SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; <BR> SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; <BR> SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; <BR> SPI_InitStructure.SPI_BaudRatePrescaler = <BR> SPI_BaudRatePrescaler_128; <BR> SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; <BR> SPI_InitStructure.SPI_CRCPolynomial = 7; <BR> SPI_Init(SPI2, &SPI_InitStructure); <BR> <BR> // enable SPI2 <BR> SPI_Cmd(SPI2, ENABLE); <BR> <BR> <BR> /************************************** <BR> * End Accel. Config <BR> **************************************/ <BR>

Here is my code to test it. It is just a simple while loop to make sure I'm reading the right register.

Code:

<BR> <BR> Address = 0xA0; <BR> SendByte(Address); <BR> while(1){ <BR> <BR> Address = 0xA0; <BR> ReceivedData = SendByte(Address); <BR> printf(''Cntrl_Reg1: %x nr'', ReceivedData); <BR> <BR> Address = 0xA1; <BR> ReceivedData = SendByte(Address); <BR> printf(''Cntrl_Reg2: %x nr'', ReceivedData); <BR> <BR> Address = 0xA2; <BR> ReceivedData = SendByte(Address); <BR> printf(''Cntrl_Reg3: %x nr'', ReceivedData); <BR> } <BR>

Then, here is my SendByte function.

Code:

<BR>/******************************************************************************* <BR>* Function Name : SendByte <BR>* Description : Sends the input byte on the SPI, then returns a the byte <BR>* recieved from the SPI device. <BR>* Input : byte: The byte to be sent to the SPI device. <BR>* Output : None <BR>* Return : The byte returned by the SPI device. <BR>*******************************************************************************/ <BR>u8 SendByte( u8 byte ) <BR>{ <BR> u8 ReturnData; <BR> <BR> <BR> SPI_Cmd(SPI2, ENABLE); <BR> // set chip select low <BR> GPIO_WriteBit( GPIOB, GPIO_Pin_10, Bit_RESET ); <BR> <BR> <BR> /* Loop while DR register in not empty */ <BR> while( SPI_I2S_GetFlagStatus( SPI2, SPI_I2S_FLAG_TXE ) == RESET ); <BR> <BR> /* Send byte through the SPI2 peripheral */ <BR> SPI_I2S_SendData( SPI2, byte ); <BR> <BR> /* Wait to receive a byte */ <BR> while( SPI_I2S_GetFlagStatus( SPI2, SPI_I2S_FLAG_RXNE ) == RESET ); <BR> <BR> ReturnData = SPI_I2S_ReceiveData( SPI2 ); <BR> <BR> // set chip select high <BR> GPIO_WriteBit( GPIOB, GPIO_Pin_10, Bit_SET ); <BR> <BR> SPI_Cmd(SPI2, DISABLE); <BR> /* Return the byte read from the SPI bus */ <BR> return ReturnData; <BR> <BR> <BR>} <BR>

[ This message was edited by: atkranz on 10-04-2009 04:05 ]

fat031cc
Associate II
Posted on May 17, 2011 at 13:09

Hello atkranz,

I am not sure, but probably CS signal is not working properly..

Are you able to check it with oscilloscope ?

In my project that worked with LIS302DL, I used following code to initialize ChipSelect pin:

Code:

....

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

atkranz
Associate II
Posted on May 17, 2011 at 13:09

Thanks for the idea. I tried that once before, and it didn't work. I just tried it again, and I get ff out on the line no matter what I read.

I think you are probably right on the CS though, but the oscilloscopes we have suck, and I can't see anything.

The accelerometer I am using is in fact the LIS302DL.

Edit:

Do I need to use the SPI_NSSInternalSoftwareConfig function to toggle the CS? What I'm asking is: is me manually trying to do it by setting or resetting the bit wrong?

As you can see, the CS is hooked up to PB10, so I don't see how I could use SPI_NSS to do anything. So I think I need to manually do this.

[ This message was edited by: atkranz on 10-04-2009 20:54 ]

domen2
Associate III
Posted on May 17, 2011 at 13:09

Doing it manually and having pin initialized as Out_PP GPIO should work. Works here ;)