|
SPI双机通信,主机大概100ms发送一次数据一直发,从机DMA接收,SPI 接收完后发送一个消息给任务拷贝数据,数据拷贝完成后开启下一帧DMA接收数据(HAL_SPI_Receive_DMA(&hspi1, (uint8_t *)g_spiRxBuf, sizeof(SPI_Data));),数据拷贝任务优先级最高死等接收完成消息。现在发现问题从机偶尔(半个钟,一两个钟都可能)接收错误,进入HAL_SPI_ErrorCallback这里,现在不知道什么原因导致接收错误。现在想进入错误后如何复位SPI重新接收数据。
0x38000000地址mpu配置参考V7的SPI双机通信(从机):
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x38000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER6;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
接收完成发送消息操作
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
SPI_MSG_T MSG;
MSG.type = SPI_CMD_TYPE_READ_DATA;
osMessageQueuePut(Spi1_RxHandle, (void *)&MSG, 0, 0);
wTransferState = TRANSFER_COMPLETE;
}
这样操作没法复位让SPI重新接收正确的数据,就是一直都是进入这个函数了
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
wTransferState = TRANSFER_ERROR;
if(hspi->Instance==SPI1)
{
__disable_irq();
__HAL_DMA_DISABLE(hspi->hdmarx);
SCB_InvalidateDCache_by_Addr((uint32_t *)g_spiRxBuf, sizeof(SPI_Data)); //g_spiRxBuf 地址在0x38000000。
HAL_SPI_Receive_DMA(&hspi1, (uint8_t *)g_spiRxBuf, sizeof(SPI_Data));
__enable_irq();
}
}
|
|