2024-04-30 05:28 AM
Sorry, I have another question to ask everyone.
I am currently using the STM32F429ZIT6 to receive data from the AD7366 via SPI.
My Code:
int main(){
/*
Initialize all configured...
*/
while(1){
/* CNVST Enable */
GPIOA->ODR &= 0x0FF7F;
/* Waiting BUSY */
while(!(GPIOA->IDR & 0x8000));
GPIOA->ODR |= 0x0080;
while(GPIOA->IDR & 0x8000);
/* CS Enable */
GPIOA->ODR &= ~(1<<4);
HAL_SPI_Receive(&hspi1, data_ptr, 1, 1);
/* CS Disable */
GPIOA->ODR |= 0x0010;
}
}
When I use a slower SPI frequency, both the timing and the data are correct.
If SPI Config hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128:
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_RXONLY;
hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
RXNE Reset & DR Data is Correct
Blue is CS, Yellow is SCK
However, when I set the SPI frequency to be faster, errors occur.
If SPI Config hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64:
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_RXONLY;
hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
RXNE no Reset
Blue is CS, Yellow is SCK
I have checked the STM32F429 Errata sheet[1] write:
master receive-only mode (simplex receive or half-duplex bidirectional receive phase) and an SCK strobing
edge has not occurred since the transition of the RXNE flag from low to high.
I'm not sure if this is the cause. If RXNE is causing the issue, how can this be resolved on STM32F4 in general?
Thank you all.
[1] STM32F427/437 and STM32F429/439 device errata - Errata sheet
2024-08-06 05:11 AM
Hello @Scarlet ,
Maybe some articles on the STM32MCU wiki will help you.
For example this one on SPI.
Best Regards
Michael
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2024-08-06 12:56 PM
The (full text of the) errata you reference just says in 2 line RX only mode, ignore the BUSY flag. The HAL F4xx library does that. At least in CubeF4 1.26.1.
It looks like the HAL_SPI_Receive() code doesn't disable the SPI port fast enough when the clock divisor is 64. Kinda hard to believe. What is your SYSCLK frequency?
I have no experience with "master receive only" mode. I've seen lots (several?) comments on this forum that people have not been able to get the the 2 wire master RX only mode to work. The suggested solution is usually to configure the SPI in normal 3 wire (sck, mosi, miso) mode, then manually re-configure the MOSI (i.e. TX) pin as general GPIO or whatever other function you need. Then the HAL_SPI_Receive() function just calls HAL_SPI_TransmitReceive(). In that mode, the transfers are triggered by a write to the SPI DR instead of "keep receiving until I disable the port" in RX ONLY mode.
2024-08-06 01:09 PM
Receive-only mode puts the clock in free-running mode which means you have a race condition between disabling the SPI and the clocks coming out.
I'd recommend using 4-wire mode with HAL_SPI_TransmitReceive and leaving the MOSI pin disconnected if you cannot allow the extra clocks.