cancel
Showing results for 
Search instead for 
Did you mean: 

No Incoming data through MISO, What can my mistake be ?

KOzdi
Associate II

I am new in SPI protocol and trying to perform an application with LORA-Ra02 module via SPI protocol. I can send data through MOSI by considering DataFrame, CPOL, CPHA, rw bit of the frame but I cannot receive any data through MISO. I performed this application with both STM32 and Arduino to compare the differences. I want to share some picture and code to be understood better.

This is the picture of trying with Stm32f103, no incoming data :

0690X000006C9imQAC.jpg

This is the picture of trying with arduio, Datas must be like in this picture actually :

0690X000006C9irQAC.jpg

This is the information about SPI protocol of LORA Ra-02 module :

0690X000006C9iwQAC.jpg

This is the codes I wrote :

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_spi.h"
 
 
#define SPIx_RCC      RCC_APB2Periph_SPI1
#define SPIx          SPI1
#define SPI_GPIO_RCC  RCC_APB2Periph_GPIOA
#define SPI_GPIO      GPIOA
#define SPI_PIN_MOSI  GPIO_Pin_7
#define SPI_PIN_MISO  GPIO_Pin_6
#define SPI_PIN_SCK   GPIO_Pin_5
#define SPI_PIN_SS    GPIO_Pin_4
 
void SPIx_Init(void);
uint8_t SPIx_Transfer(uint8_t data);
void SPIx_EnableSlave(void);
void SPIx_DisableSlave(void);
 
uint8_t receivedByte;
 
void delay(unsigned long int time){
	
unsigned long c;
for(c=1; c<=time; ++c); // some delay
 
}
 
int main()
{
 
	// Initialization struct
    SPI_InitTypeDef SPI_InitStruct;
    GPIO_InitTypeDef GPIO_InitStruct;
 
    // Step 1: Initialize SPI
    RCC_APB2PeriphClockCmd(SPIx_RCC, ENABLE);
    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
    SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
    SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
    SPI_Init(SPIx, &SPI_InitStruct); 
    SPI_Cmd(SPIx, ENABLE);
 
    // Step 2: Initialize GPIO
    RCC_APB2PeriphClockCmd(SPI_GPIO_RCC, ENABLE);
    // GPIO pins for MOSI, MISO, and SCK
    GPIO_InitStruct.GPIO_Pin = SPI_PIN_MOSI | SPI_PIN_MISO | SPI_PIN_SCK;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SPI_GPIO, &GPIO_InitStruct);
    // GPIO pin for SS
    GPIO_InitStruct.GPIO_Pin = SPI_PIN_SS;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SPI_GPIO, &GPIO_InitStruct);
 
    // Disable SPI slave device
    SPIx_DisableSlave();
		
		
		receivedByte = SPIx_Transfer(0x22);
 
	
  while(1) 
	{
		
 
	
	}
}
uint8_t SPIx_Transfer(uint8_t data)
{ 
		uint8_t receivedOne;
	
		SPIx_EnableSlave();
		delay(1000);
    // Write data to be transmitted to the SPI data register
	
    SPIx->DR = data;
    // Wait until transmit complete
    while (!(SPIx->SR & (SPI_I2S_FLAG_TXE)));
	
	delay(1000);
	
    // Wait until receive complete
    while (!(SPIx->SR & (SPI_I2S_FLAG_RXNE)));
    // Wait until SPI is not busy anymore
    while (SPIx->SR & (SPI_I2S_FLAG_BSY));
    // Return received data from SPI data register
    receivedOne = SPIx->DR;
	
	  SPIx_DisableSlave();
 
		return receivedOne;
}
 
void SPIx_EnableSlave()
{
    // Set slave SS pin low
    SPI_GPIO->BRR = SPI_PIN_SS;
}
 
void SPIx_DisableSlave()
{
    // Set slave SS pin high
    SPI_GPIO->BSRR = SPI_PIN_SS;
}

What seems to be my problem ?

Thanks in advance !

16 REPLIES 16

An off-the-wall question: In this line,

SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;

...what's the "SPI_NSSInternalSoft_Set" intended to do?

KOzdi
Associate II

it's all about slave select pin management. It affects SSM and SSI bit in the SPI->CR1 register. That pair of bit is used to select either software select or hardware select.

From the datasheet :

SSI: This bit has an effect only when the SSM bit is set. The value of this bit is forced onto the 

NSS pin and the IO value of the NSS pin is ignored.

SSM: When the SSM bit is set, the NSS pin input is replaced with the value from the SSI bit.

This time I tried RFID-RC522 card to communicate again there is no incoming data on the MISO line. It seems I am doing something wrong in the code

Bob S
Principal

I don't know about the F10x family, but on the L4 you need to set an additional member in the GPIO_InitStruct. In my case (on the L4), using SPI1 it is:

GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;

The GPIO_Mode (that you DO configure) tells the GPIO init function to map these pins to alternate functions. The "Alternalte" settings tells the GPIO init function *WHICH* alternate function to map to these pins (each pin has multiple alternate functions available. If that structure member exists and you are not setting it, you get either zero or some random value - either of which means it won't work.

KOzdi
Associate II

There is no such configuration in F10x family. If so, My former I2C examle should haven't worked. Also I found some code about spi in f10x family, They did gpio configuration like me.

KOzdi
Associate II

The question in my mind with regard to spi communication is

While sending data through MOSI, sck is generated by master in this line:

SPIx->DR = data;

After that, We are waiting for some events to happen like this :

  while (!(SPIx->SR & (SPI_I2S_FLAG_TXE)));

  // Wait until receive complete

  while (!(SPIx->SR & (SPI_I2S_FLAG_RXNE)));

  // Wait until SPI is not busy anymore

  while (SPIx->SR & (SPI_I2S_FLAG_BSY));

  // Return received data from SPI data register

In fact, since communication is full-duplex, While sending data to slave , at the same time we are receiving dummy data and RXNE is set. Without waiting actual received data, We are proceeding to disable slave and end communication.

This might be the idea about my issue

T J
Lead

this code works...

you can see the fastTX doesnt wait unless its busy...

but receive has to wait for the data to leave the pin before it can receive...

void SPI_t::fastTransfer(unsigned short data) {
//    Clear_SPI1_nSS_Out();
 
    char RxSPI;
    while (!(hspi1.Instance->SR  & SPI_FLAG_TXE))
        ;     // wait for the last transfer to complete
    *((__IO uint8_t *)&hspi1.Instance->DR) =  data;
 
    // clear receive buffer and dump data
    while ((hspi1.Instance->SR  & SPI_FLAG_RXNE))
        RxSPI = hspi1.Instance->DR; 
//    Set_SPI1_nSS_Out();        
}
 
 
unsigned char SPI_t::transfer_receive(unsigned short data) {
 
    char RxSPI;
 //   Clear_SPI1_nSS_Out();
    while (!(hspi1.Instance->SR  & SPI_FLAG_TXE))
         ;     // wait for the last transfer to complete
 
    *((__IO uint8_t *)&hspi1.Instance->DR) = data;	// force the SPI to transceive 8 bit
 
    while (!(hspi1.Instance->SR  & SPI_FLAG_TXE))
        ;   // wait for this Tx fifo to clear
 
    while ((hspi1.Instance->SR  & SPI_FLAG_BSY))
        ;  // wait for the data to leave the pin
 
// read out all Rx bytes only keep the last one.
    while ((hspi1.Instance->SR  & SPI_FLAG_RXNE))
        RxSPI = hspi1.Instance->DR; 
 
 //   Set_SPI1_nSS_Out();        
    return RxSPI;
}

KOzdi
Associate II

I see, this is already what I did as it is seen above. The point I need to understand is

let's say I will send 8 bit data to slave and will receive 8 bit info. How to handle these 16 bit ? Outgoing and incoming data in one body of 16 bit or separately ?

This seems about DataFrame, I think this is the point I make the miskate. I suppose like this :

I will configure dataframe as 8 bit because I will send 8 bit and receive 8 bit. I can send data of 8 bit without problem but no incoming data. I was supposing something like slave device trigger master's SCK and incoming data will be received but in vain.

Even if datas are 8 bit, they must be considered together that is in one body of 16 bit

As you see in my code my dataframe and parameter of transfer function is 8 bit.

Probably Arduino example made me confused