cancel
Showing results for 
Search instead for 
Did you mean: 

cant read a register with SPI

MSimo.1
Associate II

Hey There,

Ive got a Semtech SX1261 Board (LoRa- tranceiver) and iam trying to read its registers with my STM32L432KC (with SPI)

Ive got working arduino code to read all its registers, but its giving me different results when i try the same thing with my STM controller..

I tried to reduce the problem to the bare minimum ( read a single 1 byte register) buts its giving me wrong results... I read the datasheet and configured my SPI Interface in the .ioc file (CPOL, CPHA, max freq and the used pins)

I don't know what else I could try now .. so iam asking you guys.

Any help/tips would be super nice!

Firstoff the arduino code :

void loop()
{  uint16_t add = 0x8E1; // The Register i want to read
  uint8_t addr_l, addr_h;
 
  addr_h = add >> 8;
  addr_l = add & 0x00FF;
 
  Serial.print("MSB: ");
  Serial.print(addr_h);
  Serial.print("   LSB: ");
  Serial.print(addr_l);
  Serial.print("   addr: ");
  Serial.println(add);
  
  checkBusy();
  
  digitalWrite(NSS, LOW);
  SPI.transfer(RADIO_READ_REGISTER);  //0x1D
  SPI.transfer(addr_h);               //MSB
  SPI.transfer(addr_l);               //LSB
  SPI.transfer(0xFF);
 
  uint8_t data = SPI.transfer(0xFF); 
  
  digitalWrite(NSS, HIGH);
 
  checkBusy();
    Serial.println(data);
  delay(5000);
}
 
Output : 
MSB: 8   LSB: 225   addr: 2273 (decimal)
57  (decimal)

now my STM Code :

while(1) {
            uint16_t add = 0x8E1; // address i want to read ; result should be 57 in DEC
	    uint8_t addr_l, addr_h;
 
	    addr_h = add >> 8;
	    addr_l = add & 0x00FF;
 
	    checkBusy();
 
	    HAL_GPIO_WritePin(SX1261_NSS_GPIO_Port, SX1261_NSS_Pin, GPIO_PIN_RESET);
 
	    uint8_t rrg = RADIO_READ_REGISTER; //0x1D
	    uint8_t term = 0xFF;
	    
	    HAL_SPI_Transmit(&hspi1, &rrg,1, HAL_MAX_DELAY);
	    HAL_SPI_Transmit(&hspi1, &addr_h,1, HAL_MAX_DELAY);
	    HAL_SPI_Transmit(&hspi1, &addr_l,1, HAL_MAX_DELAY);
	    HAL_SPI_Transmit(&hspi1, &term,1, HAL_MAX_DELAY);
 
 
	    uint8_t spirxbuff=0;//[4] ={0};
	    //HAL_SPI_Receive(&hspi1, &spirxbuff, 1, HAL_MAX_DELAY);
	    HAL_SPI_TransmitReceive(&hspi1, &term, &spirxbuff, 1, HAL_MAX_DELAY);
 
	    HAL_GPIO_WritePin(SX1261_NSS_GPIO_Port, SX1261_NSS_Pin, GPIO_PIN_SET);
 
	    checkBusy();
		char s1[100] ;
		sprintf(s1,"MSB: %i LSB: %i addr = %i ; %x \r\n",addr_h, addr_l, add,spirxbuff);
		tx_com((uint8_t*)s1, strlen(s1));
 
	  HAL_Delay(3000);
}

the output is :

MSB: 8 LSB: 225 addr = 2273 ; 8 

the problem is that the value of the read register is wrong (8 instead of 57)

this is my SPI_Init funcion:

static void MX_SPI1_Init(void)
{
 
  /* USER CODE BEGIN SPI1_Init 0 */
 
 
 
  /* USER CODE END SPI1_Init 0 */
 
  /* USER CODE BEGIN SPI1_Init 1 */
 
  /* USER CODE END SPI1_Init 1 */
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_4BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */
	__HAL_SPI_ENABLE(&hspi1);
  /* USER CODE END SPI1_Init 2 */
 
}

thank you very much!

17 REPLIES 17
TDK
Guru

> hspi1.Init.DataSize = SPI_DATASIZE_4BIT;

Is this intended? Seems like it should be SPI_DATASIZE_8BIT.

If you feel a post has answered your question, please click "Accept as Solution".
MSimo.1
Associate II

It was not ... i changed it to 8 Bits Data Size.

Not iam getting 0 everytime:(

I tried different registers, the result is 0 everytime...

MSimo.1
Associate II

I just tried changing it to 16Bit..

i get some numbers (they differ if i read a different register)

but still not the right number :>

i get 0x51 instead of 0x35 for example ....

KnarfB
Principal III

There is a I-CUBE-LRWAN LoRaWAN software expansion from STM which has board support packages for various modules.

ive already seen that .. this looks way to complicated for me.

i just want to send LoRa Messages Point to Point between two tranceivers..

and i already have the Arduino Code to do that.

I just have to solve this register read/write problem:(

it cant be that hard to read a right value from a register, right?

TDK
Guru

Send a dummy byte prior to pulling CS low.

A logic analyzer would tell you what's going on pretty quickly. Hard to do hardware development without one.

If you feel a post has answered your question, please click "Accept as Solution".

Adding one (or two) dummy transmits did not change anything..

i Should make clear, that iam rading the register in the wile(1) loop. So it gets read every 3 secs.

The result of the first time (after the Controller boots) has a different result than the other .. i dont know if thats important..

the Output is :

STM32 Reset 
Reset device 
data= 17 = 0x11  
Reset device 
data= 81 = 0x51  
Reset device 
data= 81 = 0x51  ....

i just hooked my Oscilloscope to the SPI lines .. the voltage levels on MISO seem to drop if i change SPI_DATASIZE_16BIT; to 8 BIT .. why is that?

theese measurements are with 8 bit : (result is always 0)

0693W000003POu0QAG.png 0693W000003POu5QAG.png

the next 2 pictures is with the same code, but the Data_length changed to 16 (wich gives me wrong results (bit not 0)):

0693W000003POuKQAW.png0693W000003POuFQAW.png

i hope this helps ..

TDK
Guru

Your scope is suggesting the voltage level is ~0.33V. Are you using probes in 1x mode instead of 10x mode?

Why are you using SPI_DATASIZE_16BIT at all? If you want to send 8 bits per transaction, use 8 bits per transaction.

Your NSS line is toggling mid-transaction. That's no good. Could be noise.

0693W000003POyqQAG.png

In any case, you're going to need to zoom in on MOSI/SCK closer to see values of individual bits. If those bits are correct, then the STM32 code is not the problem and there is some other reason the IC is not responding correctly.

If you feel a post has answered your question, please click "Accept as Solution".
LMI2
Lead

I had problems with SPI, too. I did a program which handled GPIO pins directly. That showed what would work. I had add pull up resistors to MOSI, MISO and CLK and really read the datasheet. After that was working, I did the same with HW SPI. I had to adjust clock polarity and phase and then it started to work. Perhaps you should try the same. Logic analyser is necessary I think. I borrowed a Dreamsourcelab LA from a friend. New would cost about 200€£$