Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

If you are using SPI mode "Receive Only Master" on STM32 F4 read this! #1

Closed
SimpleMethod opened this issue Aug 18, 2021 · 0 comments
Closed
Labels
good first issue Good for newcomers

Comments

@SimpleMethod
Copy link
Owner

SimpleMethod commented Aug 18, 2021

If you are using SPI in "Receive Only Master" mode you will most likely not be able to read the data properly.
In my case the problem was with the SCK line was always in high state and loss of the first data frame.
The solution to the problem is to set the SCK pin to "pull-down" and read array on first element instead of zero. An additional safeguard is to restart the SPI interface as advised in the thread:
https://www.eevblog.com/forum/microcontrollers/stm32-spi-slave-inconsistent/
Below is the prepared code for this mode, be sure you change __HAL_RCC_SPI3_FORCE_RESET and __HAL_RCC_SPI3_RELEASE_RESET to the correct SPI used in your project

void MAX31855_ReadData(MAX31855_StateHandle *MAX31855){
/* Code from the thread: https://www.eevblog.com/forum/microcontrollers/stm32-spi-slave-inconsistent/ Author: DavidAlpha*/
if((MAX31855->hspi->State>HAL_SPI_STATE_READY) && (MAX31855->hspi->State<HAL_SPI_STATE_ERROR)){	// Handler BUSY in any mode (But not error or reset);
MAX31855->hspi->State=HAL_SPI_STATE_READY;	// Force ready state
}
if((MAX31855->hspi->Instance->SR & SPI_SR_BSY) || (MAX31855->hspi->State!=HAL_SPI_STATE_READY)){	// If peripheral is actually busy or handler not ready
	MAX31855->hspi->State=HAL_SPI_STATE_RESET;	// Force reset state (HAL_SPI_Init will fail if not in reset state)
 
	__HAL_RCC_SPI3_FORCE_RESET();		// Change to the SPI used in the project
	asm("nop\nnop\nnop\nnop");		// Wait few clocks just in case
	while(MAX31855->hspi->Instance->SR & SPI_SR_BSY);	// Wait until Busy is gone
	__HAL_RCC_SPI3_RELEASE_RESET();		// Change to the SPI used in the project
	asm("nop\nnop\nnop\nnop");		// Wait few clocks just in case
	while(MAX31855->hspi->Instance->SR & SPI_SR_BSY);	// Check again
	if (HAL_SPI_Init(MAX31855->hspi) != HAL_OK){ Error_Handler(); }		// Re-init SPI
/**/		
	
uint8_t payload[5];
int32_t frame;
MAX31855_SetNSSState(MAX31855,GPIO_PIN_RESET);
HAL_SPI_Receive(MAX31855->hspi, payload, 5, 1000);
MAX31855_SetNSSState(MAX31855,GPIO_PIN_SET);
MAX31855->scvFault=0;
MAX31855->scgFault=0;
MAX31855->ocFault=0;
MAX31855->fault=0;
MAX31855->extTemp=0;
MAX31855->extTempSign=0;
MAX31855->intTemp=0;
MAX31855->intTempSign=0;
 
frame = payload[1];
frame = frame<<8;
frame = frame|payload[2];
frame = frame<<8;
frame = frame|payload[3];
frame = frame<<8;
frame = frame|payload[4];
int32_t extTemp=frame;
int32_t intTemp=frame;
 
if(frame& 0b00000000000000000000000000000100)
{
MAX31855->scvFault=1;
}
if(frame& 0b00000000000000000000000000000010)
{
MAX31855->scgFault=1;
}
if(frame& 0b00000000000000000000000000000001)
{
MAX31855->ocFault=1;
}
if(frame&0b00000000000000010000000000000000)
{
MAX31855->fault=1;
}
if(frame&0b10000000000000000000000000000000)
{
MAX31855->extTempSign=1;
}
if(frame&0b00000000000000010000000000000000)
{
MAX31855->intTempSign=1;
}
 
extTemp>>=18;
if (MAX31855->intTempSign) {
extTemp = ~(extTemp & 0b11111111111111);
}
MAX31855->extTemp=extTemp;
 
intTemp = ((intTemp>>4) & 0b11111111111);
if (MAX31855->intTempSign)
{
intTemp=~(intTemp|0b1111100000000000); //Experimental code, not tested!
}
MAX31855->intTemp=intTemp;	
}
@SimpleMethod SimpleMethod added the good first issue Good for newcomers label Aug 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

1 participant