cancel
Showing results for 
Search instead for 
Did you mean: 

F4Discovery SPI troubles

chrispadbury
Associate II
Posted on July 05, 2012 at 14:42

The original post was too long to process during our migration. Please click on the attachment to read the original post.
9 REPLIES 9
Posted on July 05, 2012 at 15:22

Got some real issues with your while() loops there. (hint: missing semicolons)

SPI1 references mixed in.

I might attack this something like this, working from memory not tested :

int main(void)

{

char Received_From_device[500] = ''''; // Maximum data from device of 500 bytes

//char character[10] = '''';

char ETX_character;

int i,a,lazy_timeout_counter,lazy_timeout_max,tmp,adc_value;

char c;

RCC_Configuration();

GPIO_Configuration();

SPI2_Configuration(); //SPI configure

USART1_Configuration();

GPIO_SetBits(GPIOB, GPIO_Pin_12); //set Chip Select HIGH for SPI

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // Wait for Empty

USART_SendData(USART1, 0x49); // Send 'I'

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

USART_SendData(USART1, 0x42); // Send 'B'

SPI_Loop:

Delay(1000); //1second delay

//goto Jump2Here;

//Select CH0 of LTC2492

GPIO_ResetBits(GPIOB, GPIO_Pin_12); // Assert -CS

Delay_us(10); // overkill

// You need semicolons after the whiles otherwise they repeat the next statement

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 0); //wait for transmit buffer to be empty, should be

SPI_I2S_ReceiveData(SPI2); // Clear RXNE

SPI_I2S_SendData(SPI2, LTC_Internal_Temperature_select); //LTC_Internal_Temperature_select

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 0); //wait for transmit buffer to not be empty (ie data loaded in)

SPI_I2S_SendData(SPI2, 0); // Fill for 32-bits, remaining 16-bits in holding buffer

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == 0); // wait for last bit to be sent

SPI_I2S_ReceiveData(SPI2); // Clear RXNE, first word

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == 0); // wait for last bit to be sent

SPI_I2S_ReceiveData(SPI2); // Clear RXNE, second word

Delay_us(10);

GPIO_SetBits(GPIOB, GPIO_Pin_12); // Release -CS

Delay(1000); //1second delay

//await result readable via SPI and read in result via SPI two 16bit reads over SPI

GPIO_ResetBits(GPIOB, GPIO_Pin_12); // Assert -CS

Delay_us(10); // overkill

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 0); // should be empty

SPI_I2S_ReceiveData(SPI2); // clear RXNE

SPI_I2S_SendData(SPI2, LTC_Internal_Temperature_select); // send command word

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 0); //wait for transmit buffer to not be empty (ie data loaded in)

SPI_I2S_SendData(SPI2, 0); // Fill for 32-bits, remaining 16-bits in holding buffer

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == 0);

tmp = SPI_I2S_ReceiveData(SPI2); // read word from receive buffer, high order 16-bits

adc_value = tmp * 65536;

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == 0); // wait until receive buffer is not empty

tmp = SPI_I2S_ReceiveData(SPI2); // read word from receive buffer, low order 16-bits

adc_value = adc_value + tmp;

Delay_us(10);

GPIO_SetBits(GPIOB, GPIO_Pin_12); // Release -CS

Jump2Here:

//send result via RS232

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

USART_SendData(USART1, 0x43); // Send 'C'

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

USART_SendData(USART1, 0x48); // Send 'H'

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

USART_SendData(USART1, 0x30); // Send '0'

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

USART_SendData(USART1, 0x3A); // Send ':'

// Sends as binary, not ascii

//adc_value = 1234567890;

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

USART_SendData(USART1, ((adc_value >> 24) & 0xFF));

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

USART_SendData(USART1, ((adc_value >> 16) & 0xFF));

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

USART_SendData(USART1, ((adc_value >> 8) & 0xFF));

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

USART_SendData(USART1, ((adc_value >> 0) & 0xFF));

//goto SPI_Loop;

while (1);

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
chrispadbury
Associate II
Posted on July 05, 2012 at 15:35

Thanks Clive, sloppy with my ;s

I have connected up the scope and MISO of LTC2492 goes up and down when not connected to SMT32, but not when connected. This suggests that MISO of the STM32 is configured as an output (PB14). How do I fix that?

chrispadbury
Associate II
Posted on July 05, 2012 at 15:52

Looking at the code I tried adding in a line at the end of the SPI_Configuration routine that reads:

GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);

This seems to have worked. Could a similar line for PB12 fix the Chip Select? I might try that.

My code is pretty rough here

Posted on July 05, 2012 at 16:25

Yeah, just noticed the AF Config as I read through your response

GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);

Yes, you would need to mux the pin to the AF device, which also controls the pin directions, so deals with 1-wire or Master/Slave settings, etc.

I understand the roughness issue, having mashed out similar code myself trying to make sense of things, and try a couple of avenues. Added or missing semicolons on whiles being particularly easy to overlook.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
chrispadbury
Associate II
Posted on July 05, 2012 at 17:08

I'll try that with NSS when I get the chance. Lots of people seem to have trouble with NSS and bit bashing seems to often be the solution people go for. Would be nice to have a better solution though.

chrispadbury
Associate II
Posted on July 05, 2012 at 17:38

Well I have tried it and NSS is still a mystery to me. I added the following line to the SPI_Configuration routine:

GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_SPI2);

 

I added GPIO_Pin_12 to the GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; line

I then attempted to use SPI_Cmd(SPI2, DISABLE); and SPI_Cmd(SPI2, ENABLE); to control NSS (CS_bar HIGH and LOW respectively) but PB12 doesn't move from being permanently LOW. I can see the SPI clock (PB13) float when the SPI is disabled.

If I change SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; to SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; then it stalls on the first while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 0) line.

understanding how to use NSS properly would make the code a lot cleaner and more intuative.
dthedens23
Associate II
Posted on March 19, 2013 at 01:05

Philosophy ON

when I see something like this I just cringe!

GPIO_SetBits(GPIOB, GPIO_Pin_12); // Release -CS

and thanks clive1 for adding the comment

Embedded developers should read ''Clean Code''

GPIO_SetBits(GPIOB, GPIO_Pin_12);

is completely un-maintainable.   Who knows that it it the chip select?  Only the person who is married to the code.  Suppose Hardware changes the pin?  Then you have to find all the instances throughout the code and change them all (hopefully).

My goal is to write code that is self documenting code so that I do not write comments (which are often wrong anyway).  So that I can give this code to junior engineers and they can learn and maintain it.

Philosophy OFF

Posted on March 19, 2013 at 01:29

Yeah, would always prefer code to be understandable even if comments were removed.

You might find this an entertaining example

[DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/f407%20board%20with%20examples&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&TopicsView=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/AllItems.aspx&currentviews=65]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fSTM32Discovery%2ff407%20board%20with%20examples&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&TopicsView=https%3A%2F%2Fmy.st.com%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Discovery%2FAllItems.aspx¤tviews=65
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dthedens23
Associate II
Posted on March 19, 2013 at 21:43

more magic numbers than I have ever seen before. :)

Bypass CMSIS?

And what happens when a peripheral lib is updated because of some silicon issue?

totally un-maintainable.  And this is ''for students''? (if the translation is correct)