Skip to main content
YBAYR.1
Associate III
April 24, 2025
Question

I could not convert the HAL_SPI_TransmitReceive function to LL

  • April 24, 2025
  • 5 replies
  • 1030 views

I AM TRYING TO CONTROL WITH CLRC SPI. MY PROJECT IS WRITTEN WITH LL. I CANNOT ADAPTE THIS FUNCTION. CAN YOU PLEASE HELP ME?

 

https://github.com/CodElecCz/STM32F1-CLRC663

5 replies

YBAYR.1
YBAYR.1Author
Associate III
April 24, 2025

YBAYR1_0-1745509309913.pngYBAYR1_1-1745509331754.png

I SET IT LIKE THIS BUT IT DID NOT WORK

TDK
Super User
April 24, 2025

Please don't use all caps, it is distracting.

 

Is the SPI initialized? Show this.

Show the state of the SPI registers when it is not working.

"If you feel a post has answered your question, please click ""Accept as Solution""."
YBAYR.1
YBAYR.1Author
Associate III
April 24, 2025

yes spi started there is no problem, attached is the image

YBAYR1_0-1745510836837.png

 

YBAYR.1
YBAYR.1Author
Associate III
April 24, 2025

I think the data order is mixed up, I am doing the same as the example in github.

 

YBAYR.1
YBAYR.1Author
Associate III
April 29, 2025

Duplicate - merged.

Please don't start multiple threads on the same topic.


Hello dear friends,

I have an STM32L433 project written using the Low Layer (LL) library, and I’m trying to integrate the CLRC663 NFC reader into it. However, I’ve been struggling to convert the HAL_SPI_TransmitReceive function into its equivalent using only LL functions. I cannot use the HAL library at all, since there are other slave devices in the system and compatibility issues arise.

I’ve searched the internet and found some LL-based SPI examples, some of which I’ve attached screenshots of, but unfortunately, none of them worked. What I need is a fully functional equivalent of HAL_SPI_TransmitReceive written using only LL. Where can I find such an implementation?

Any help would be greatly appreciated.

 

WORKING CODE:

 

 
void mfrc630_SPI_transfer(const uint8_t* tx, uint8_t* rx, uint16_t len)

{

switch(HAL_SPI_TransmitReceive(&hspi2, tx, rx, len, 1000))

{

case HAL_OK:

// Communication is completed, dont do anything.

break;

case HAL_TIMEOUT:

printf("Timeout\n");

case HAL_ERROR:

printf("Some error\n");

Error_Handler();

break;

default:

break;

}

}

 

THE CODE THAT DOESN'T WORK AND I TRY TO WRITE WITH LL:

 

uint8_t SPI2_ByteSend (uint8_t val)
{
LL_SPI_TransmitData8(SPI2, val);
while (LL_SPI_IsActiveFlag_BSY(SPI2));
return(LL_SPI_ReceiveData8(SPI2));
}

void mfrc630_SPI_transfer(const uint8_t* tx, uint8_t* rx, uint16_t len)
{
mfrc630_SPI_select();

for (uint16_t i = 0; i < len; i++) {
// SPI2_ByteSend her gönderilen byte'in karsiliginda dönen byte'i döner
rx[i] = SPI2_ByteSend(tx[i]);
}
mfrc630_SPI_unselect();
}

PLEASE HELP!

Andrew Neil
Super User
April 29, 2025

 

Please see How to insert source code.

 


@YBAYR.1 wrote:

THE CODE THAT DOESN'T WORK 


Saying "doesn't work" tells us next to nothing.

  • What, exactly, were you expecting it to do?
  • What, exactly, does it actually do?
  • What have you done to debug it, and find why it's doing what it does, rather than what you wanted?

See: How to write your question to maximize your chances to find a solution.

 


@YBAYR.1 wrote:

WORKING CODE:


As @TDK   already said, step through that code and understand what it's doing.

Then replicate that in your LL code.

 


@YBAYR.1 wrote:

I cannot use the HAL library at all, since there are other slave devices in the system and compatibility issues arise


What "compatibility issues", exactly ?

HAL shouldn't impose any restrictions beyond the limitations of the STM32 hardware.

Besides, you can use both LL and HAL together.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
YBAYR.1
YBAYR.1Author
Associate III
April 29, 2025

These are the codes I tried to use to replace HAL_SPI_TransmitReceive with LL-based code, but they are not working. How can I explain this more clearly? I can receive data from my CLRC663 module using full-duplex communication with HAL, but I cannot receive anything with the LL version.

 

uint8_t SPI2_ByteSend (uint8_t val)
{
	LL_SPI_TransmitData8(SPI2, val);
	while (LL_SPI_IsActiveFlag_BSY(SPI2));
	return(LL_SPI_ReceiveData8(SPI2));
}

 

void mfrc630_SPI_transfer(const uint8_t* tx, uint8_t* rx, uint16_t len)
{
	
	
 LL_GPIO_ResetOutputPin(SPI2_NSS_GPIO_Port, SPI2_NSS_Pin); // Slave Select aktif

 for (uint16_t i = 0; i < len; i++) {
 if (rx != NULL) {
 rx[i] = SPI2_ByteSend(tx[i]);
 } else {
 (void)SPI2_ByteSend(tx[i]); // RX kullanilmiyorsa sadece gönder
 }
 }

 LL_GPIO_SetOutputPin(SPI2_NSS_GPIO_Port, SPI2_NSS_Pin); // Slave Select deaktif
}

 

I WANT TO RUN THIS LIBRARY:

https://github.com/CodElecCz/STM32F1-CLRC663


 

YBAYR.1
YBAYR.1Author
Associate III
April 29, 2025

I found an example related to STM32L4, and I think the issue is related to DMA. After the first bit is sent, the slave responds immediately, but the processor misses it. This needs to be handled with DMA to avoid the issue. However, I couldn't find a suitable LL-based example. I need to rewrite the HAL_SPI_TransmitReceive function using LL, whether with DMA or another method—but it must do exactly the same job without missing anything.

HAL_SPI_TransmitReceive(&hspi2, tx, rx, len, 1000)