En el TIVAWare (TI ), posee tambien unos cuantos comandos para el tema del SPI. al principio me resulto un poco complejo entenderlo xD por que uno estaria acostumbrado a eso, como se manejan las HAL, a enviar y recibir, Lo que yo veo que ahi en las HAL de ST estan usando los mismos datos del buffer que estas usando para recibir.
Para juanjo que le gusta tanto los while
void
SSIDataPut(uint32_t ui32Base, uint32_t ui32Data)
{
//
// Check the arguments.
//
ASSERT(_SSIBaseValid(ui32Base));
ASSERT((ui32Data & (0xfffffffe << (HWREG(ui32Base + SSI_O_CR0) &
SSI_CR0_DSS_M))) == 0);
//
// Wait until there is space.
//
while(!(HWREG(ui32Base + SSI_O_SR) & SSI_SR_TNF))
{
}
//
// Write the data to the SSI.
//
HWREG(ui32Base + SSI_O_DR) = ui32Data;
}
No te enojes juanjo, tambien hay funciones que no son bloqueantes

y hacen lo mismo
Lo que si, no hay una funcion de "Enviar" y "Recibir" el DataPut sirve para enviar en su forma bloqueante o no. El DataGet simplemente lee la FIFO nada mas, asi que si tu idea es leer sos vos el que mandas un 0. Y no se asume que debes enviar un 0 o lo que sea. Como que un poco costo entender esto en mi cabeza, uno espera que poner un DataGet y recibiste.
SSIDataPut(SSI_BASE,Data);
SSIDataPut(SSI_BASE,0x00);
SSIAdvDataPutFrameEnd(SSI2_BASE, 0x00); //Esto es genial puedo controlar el CS/FSS a mi gusto!
SSIDataGet(SSI_BASE,&valor[0]); //dummy read para el primer write (generado por el "data"
SSIDataGet(SSI_BASE,&valor[0]);
SSIDataGet(SSI_BASE,&valor[1]);
Con lo cual cuando hice el driver para el Touch quedo asi. Tenia que enviar el dato, y luego recibir 16bits sin que el CS subiera, desde que escribia hasta que leia. Si ven ahi Envio los datos + 2 bytes con 0x00 a la FIFO , y luego debo leerlos.
Hay una parte fea que es la de tener que leer los datos cuando uno escribe, y que por ahi no te sirven ( especialmente en el primer dato, como se ve ) Pero eso imagino que te da la mayor flexibilidad para hacer lo que sea. Hasta ahora no tuve problemas con las librerias de TI, son todas muy basicas, funciones super simples que cargan valores a los registros directamente, incluso tienen un Macro ( HW_REG ) para acceder a la direccion que apuntan. Creo que es lo mejor poder verlo asi.