Primero describiré lo que estoy tratando de lograr, lo que he intentado y cómo no funciona; Cualquier ayuda / consejo es muy apreciado.
Tengo una MCU externa (Fotón de partículas) que actúa como SPI Master. Aproximadamente cada medio segundo debe enviar 64 bytes al STM32F103. También puede ser múltiplos de 64 bytes (por ejemplo, fragmentos de 50x64 bytes que equivalen a 3.200 bytes en este ejemplo ... máximo de fragmentos de 200x). El STM32 también tiene sus propios datos que deben devolverse a la MCU maestra, con el mismo formato.
He eliminado mucho de esto, y solo estoy tratando de que un solo intercambio de 64 bytes se realice de manera confiable, y estoy fallando en eso.
Utilicé STM32CubeMX para generar el código fuente y las configuraciones. Aquí están las funciones que estoy usando:
Búferes SPI & Bandera de inicio:
uint8_t txData[64]; //uint8_t txData[MAX_DEVICES_TRACKED * 64];
uint8_t rxData[64]; //uint8_t rxData[MAX_DEVICES_TRACKED * 64];
bool spiReady = true;
Bucle principal:
while(true)
{
if(spiReady)
{
spiReady = false;
InitSPISlave(&hspi1);
}
}
SPI inicial:
void InitSPISlave( SPI_HandleTypeDef *spiHandler )
{
memset(rxData, 0, sizeof(rxData));
HAL_SPI_TransmitReceive_IT(spiHandler, txData, rxData, sizeof(txData));
}
devoluciones de llamada que se producen después de completar SPI TXRX y devolución de llamada de error:
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
printf("SP1 Data Received: ");
for(int i = 0; i < 64; i++)
{
printf("%lx ", (long)rxData[i]);
}
printf("\n");
memset(txData, 0, sizeof(txData)); //If I don't clear the data, it comes across ok
spiReady = true;
}
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
printf("SPI1 ERROR: %d \n", hspi->ErrorCode);
spiReady = true;
}
Para realizar pruebas, tengo un temporizador que rellena periódicamente el búfer txData. Tan pronto como se complete la transacción, y la MCU maestra tenga los datos, quiero borrar el búfer txData ... cuando haya más datos disponibles, ingresará a txData, que es lo que el temporizador está simulando.
Tengo 2 problemas:
- Si comento "memset (txData, 0, sizeof (txData));" Los datos van al maestro ok. Si lo dejo como está y lo borro después de cada transacción, el maestro recibe los datos, pero el primer byte es cero o el búfer completo se desplaza un byte. Esto parece algo aleatorio. También obtengo errores SPI en la devolución de llamada de error, recibo periódicamente el error OVR "HAL_SPI_ERROR_OVR" y, finalmente, recibo los errores "HAL_SPI_ERROR_FLAG", momento en el que deja de funcionar por completo. ¿Parece que algo está sucediendo con el búfer TX del registro STM32 SPI? Pero no entiendo completamente esto, o cómo debería arreglarlo. Podría ser otra cosa, pero no estoy seguro.
- Cuando llamo "HAL_SPI_TransmitReceive_IT (spiHandler, txData, rxData, sizeof (txData));" Es muy lento para inicializar y ponerse en marcha. Decidí cronometrar esto iniciando un temporizador al llamar a esa función, y cuando se ejecuta la devolución de llamada, y toma aproximadamente 300 ms. Si aumento el tamaño de los búferes a 640 bytes, se tarda varios segundos en inicializar e iniciar la transferencia de SPI. Estoy deseando hacer un máximo de 12,800 bytes, por lo que algo está muy mal aquí, no hay ninguna razón por la que deba tomar tanto tiempo configurar una única transferencia SPI. No estoy seguro de lo que está pasando o cómo solucionar esto tampoco. Tengo que volver a llamar a esta función después de cada transferencia SPI, por lo que la MCU básicamente siempre se bloquea en un estado de inicialización durante varios segundos para recibir una sola transferencia.
Intenté cambiar a DMA SPI, p. ej. "HAL_SPI_TransmitReceive_DMA (spiHandler, txData, rxData, sizeof (txData))", y aunque es un poco más rápido para inicializar, demasiado lento, tengo los mismos problemas.
He estado rastreando Internet tratando de leer sobre esto, y la mayoría de las personas dicen que los controladores de HAL son basura y no funcionan bien, y para trabajar directamente con los registros usted mismo. Si este es el caso, no sé por dónde empezar para lograrlo ... o si tal vez haya una solución que pueda hacer para poner esto en marcha.