Skip to main content
MSimo.1
Associate III
August 14, 2020
Question

cant read a register with SPI

  • August 14, 2020
  • 17 replies
  • 4590 views

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!

This topic has been closed for replies.

17 replies

TDK
August 14, 2020

> 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
MSimo.1Author
Associate III
August 14, 2020

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
MSimo.1Author
Associate III
August 14, 2020

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
Super User
August 14, 2020

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

MSimo.1
MSimo.1Author
Associate III
August 14, 2020

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
August 14, 2020

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""."
MSimo.1
MSimo.1Author
Associate III
August 15, 2020

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
August 15, 2020

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""."
MSimo.1
MSimo.1Author
Associate III
August 15, 2020

Yes, my probe is a 10:1.

My result (from the register read) were always 0x00 when i had it at 8 Bit. This was the reason i changed it to 16 bit. I know its nonsence, but i was happy to get any data (wich is wrong, but ar least there is something..)

Picture 1 and 3 are zoomed out. you can see the 5 Transmits iam doing in my code. thats th reason NSS is pulled high 5 Times (after each transmission)

Iam still wondering about the voltage levels in Picture 1 and 3 . The blue spikes are much smaller after i switched it back to 16Bit DataLength ..? no clue

Picture 2 and 4 are zoomed in. You can see the transmission before and after the trigger pulse .. the first one is from HAL_SPI_Transmit(&hspi1, &addr_l,1, HAL_MAX_DELAY); and the second one from HAL_SPI_Transmit(&hspi1, &term,1, HAL_MAX_DELAY);

 uint16_t addr = 0x919; // ADDRESS to read
	 uint8_t term = 0xFF;
	 uint8_t rrg = RADIO_READ_REGISTER;
	 uint8_t addr_l, addr_h;
	 uint8_t spiRXbuff;
 
	 addr_h = addr >> 8;
	 addr_l = addr & 0x00FF;
 
	 checkBusy();
 
	 HAL_SPI_Transmit(&hspi1, &term,1, HAL_MAX_DELAY); // Dummy read
	 HAL_SPI_Transmit(&hspi1, &term,1, HAL_MAX_DELAY);
 
	 HAL_GPIO_WritePin(SX1261_NSS_GPIO_Port, SX1261_NSS_Pin, GPIO_PIN_RESET);
 
	 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_GPIO_WritePin(TRIGGER_GPIO_Port, TRIGGER_Pin, GPIO_PIN_SET);
	 HAL_GPIO_WritePin(TRIGGER_GPIO_Port, TRIGGER_Pin, GPIO_PIN_RESET);
 
	 HAL_SPI_Transmit(&hspi1, &term,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);

LMI2
Senior III
August 15, 2020

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€£$

MSimo.1
MSimo.1Author
Associate III
August 15, 2020

Thank you. I Read the Datasheet very carefully.

It clearly says that CPOL = 0 ; CPHA = 0 ; Motorola Data Format ,MSB First , max 10Mhz.

MSimo.1
MSimo.1Author
Associate III
August 15, 2020

So what could i try next ?

i could connect the Chip to an arduino , connect the SPI lines to the Oscilloscope and compare the Signals bit by bit?

Could it be possible that am calling the HAL_SPI_Transmit() functions right? Maybe i got the pointers wrong ? could i be sending an adress instead of proper Data?

How can this be so complicated ..

RMcCa
Senior II
August 15, 2020

Not sure what the problem is exactly but it doesn't look like the nss line is being handled properly. Is it toggleing​ during the transmission?

MSimo.1
MSimo.1Author
Associate III
August 17, 2020

alright, looks like i found the problem : 0693W000003PUiZQAW.pngis that a typical "breadboard" problem ? my project looks like that:0693W000003PUioQAG.jpgHow should i handle my NSS ? Can it be controlled by the HAL driver?

I tried to lower the Frequency and a PullDown at my NSS GPIO..

0693W000003PUkpQAG.pngshould i change something here ?

the GPIOs have a optoion called Max output frequency .. are that configurable low passes ? should i use that ?

Or Should i just solder my circuit onto a perfboard and get rid of this breadboard?

Thank you guys!

TDK
August 17, 2020
That’s literally the same thing I circled in my response two days ago.
Control the CS pin manually as a GPIO output.
"If you feel a post has answered your question, please click ""Accept as Solution""."