cancel
Showing results for 
Search instead for 
Did you mean: 

Need help with simple SPI 8 bit write driver

devinw
Associate II

Hi everyone! I was hoping to get some help on a function I've made which is called by timer to write to a DAC which takes 24 bit bytes, which I send in 8 bit chunks. I wanted to make my own function because the HAL_SPI_Transmit is oretty overhead heavy and slow to execute.

 

The thing I can't figure out is that in the below function, if I comment out the line where I wait for the TXE flag bit to set, meaning the FIFO is empty, the funciton works BUT, if I try and execute that function TWICE in the same TIM function call, it does not work. So, something is happening between calls of the TIM callback that is somehow allowing me to write to SPI again, but this doesn't seem to happen if I wait for it in my function with a while(); If I uncomment the line with a while(!((SPI->SR)&(1<<1)){}; then the thing hangs up and sits at that line forever.

I SUSPECT that I'm somehow leaving 8bits in the FIFO after my 24 bit sequence and it just stays that way forever and hangs on my line discussed above, but I don't know. Any help would be fantastically appreciated! From what I understand there is NO way to force a clear on the FIFO, so I need some otherway to do this. I couldn't figure out from the HAL_SPI_Write() function how they are doing it even though my funciton below is virtually copy and paste from the relevent parts of that function.

 

void SPI_Transmit_Fast_8bit(SPI_TypeDef *spiPortNumber, uint8_t *pData, uint8_t size) {
// This is a function made out of the "guts" of the 8-bit part of the HAL SPI send
// function with all the extra stuff removed to speed it up. It's about 25% faster
uint8_t *pTxBuffPtr = (uint8_t *)pData;
uint8_t TxXferCount = size;

if (TxXferCount > 1U) {
/* write on the data register in packing mode */
spiPortNumber->DR = *((uint16_t *) pTxBuffPtr);
pTxBuffPtr += sizeof(uint16_t);
TxXferCount -= 2U;
}
else {
*((volatile uint8_t *)&spiPortNumber->DR) = (*pTxBuffPtr);
pTxBuffPtr ++;
TxXferCount--;
}

while (TxXferCount > 0U) {
/* Wait until TXE flag is set to send data */
if ((spiPortNumber->SR)&(1<<1)) {
if (TxXferCount > 1U) {
/* write on the data register in packing mode */
spiPortNumber->DR = *((uint16_t *)pTxBuffPtr);
pTxBuffPtr += sizeof(uint16_t);
TxXferCount -= 2U;
}
else {
*((volatile uint8_t *)&spiPortNumber->DR) = (*pTxBuffPtr);
pTxBuffPtr++;
TxXferCount--;
}
}
}


//while (!((spiPortNumber->SR)&(1<<1))) {}; // wait for TXE bit to set -> This will indicate that the buffer is empty
while (((spiPortNumber->SR)&(1<<7))) {}; // wait for BSY bit to Reset -> This will indicate that SPI is not busy in communication
 
// Clear the Overrun flag by reading DR and SR
volatile uint8_t temp = spiPortNumber->DR;
temp = spiPortNumber->SR;
(void) temp;

}
0 REPLIES 0