Im using LPC1778 to simulate SSP1. The usermanual states that DR for SSP1 is at address 0x40030008. When I transmit data, I immediately receive data into the receive buffer(RNE flag in status register gets set) and also the value loaded into DR shown by Keil is not the value loaded by me into the DR.
//Send data U8 spi_send(U8 bChannelNo,U8 *pBufferPtr,U8 bLength) { U8 bDummy=0; U8 bReturn_val=0; bDummy++; bDummy=0; switch(bChannelNo) { case 0: ssp_12=LPC_SSP0; break; case 1: ssp_12=LPC_SSP1; break; case 2: ssp_12=LPC_SSP2; break; default: ssp_12=LPC_SSP0; break; } set_timeout2(10000); do { if(!(ssp_12->SR & (1<<4))) /*not busy*/ { if(ssp_12->SR & (1<<1)) /*tnf*/ { ssp_12->DR=*pBufferPtr; pBufferPtr++; bLength--; } } }while(((LPC_TIM2->TC) < (LPC_TIM2->MR1)) && ((LPC_TIM2->TC) != (LPC_TIM2->MR1)) && (bLength != 0)); if(bLength==0) { bReturn_val=1; } return bReturn_val; } //receive U8 spi_receive(U8 bChannelNo,U8 bLength,U8 *pRxDataBuff) { U8 bReturn_val=0; U8 bLoc=0; switch(bChannelNo) { case 0: ssp_12=LPC_SSP0; break; case 1: ssp_12=LPC_SSP1; break; case 2: ssp_12=LPC_SSP2; break; default: ssp_12=LPC_SSP0; break; } set_timeout2(10000); do { if(!(ssp_12->SR & (1<<4))) /*not busy*/ { if(ssp_12->SR & (1<<2)) /*rne*/ { pRxDataBuff[bLoc]=ssp_12->DR; bLength--; bLoc++; } } }while(((LPC_TIM2->TC) < (LPC_TIM2->MR1)) && ((LPC_TIM2->TC) != (LPC_TIM2->MR1)) && (bLength != 0)); if(bLength==0) { bReturn_val=1; } return bReturn_val; }
I used CMSIS driver examples for lpc1778 but still data is immediately received on sending and memory address doesnt contain the tx data. Why is Keil doing that?
Curious expression:
while(((LPC_TIM2->TC) < (LPC_TIM2->MR1)) && ((LPC_TIM2->TC) != (LPC_TIM2->MR1))
The first expression is false if TC == MR1. So why have a separate check to require that TC is != MR1?
"The chip doesn't care if you have anything connected to the MISO line - it will still sample this pin once for ever bit you transmit on the MOSI pin"- thats why the RNE flag gets for every transmit.So, il have to clear the sampled data for every transmit(2nd version of code) before proceeding to send the next byte. Conclusion is, i cant view the Tx data in memory window or in Peripherals>SSP Interface>SSP1>SSP1DR during simulation.
Since im using timer 2 to stop when TC==Match,(LPC_TIM2->TC) < (LPC_TIM2->MR1) should suffice correct. But i included the other condition just for additional checking.
"So, il have to clear the sampled data for every transmit(2nd version of code) before proceeding to send the next byte."
That would obviously depend on your usage case. Do you have anyone actually sending something to you? Do you actually care about received data? Do you see a need to care about the receive flag?
Do you have anyone actually sending something to you?- Not simultaneously, but after the master has sent out its data the slave sends out its data.
Do you actually care about received data?- Not the immediate data received when transmitting(RNE flag that getting set on TX)
Do you see a need to care about the receive flag?- Yes. Il have to clear the data out of the Rx buffer in order to receive valid data when the slave sends out its data.
The idle state for SPI communication is 0xff (or whatever word length the device is configured to send).
So it's quite common to define protocols where 0xff represents "null" data that can be thrown away.
But since SPI is always two-way, i.e. full duplex, and the slave can only send when the master sends - since the master owns the clock line and creates the bit timing - the way to implement semi-duplex communication is: - the server sends out the words of the query, while consuming and throwing away the same number of words received. - the server then sends out the same number of dummy words as the client response is long, while picking up the received words and storing in the receive buffer.
So the server needs to know how long the slave response will be. Or the server needs to be able to decode the response words one at a time to detect how long the answer is.
Please don't duplicate text like that in your answers. Use "" to show what part of the text that is quoted - quotation marks are labeled like that for a reason. It's quite confusing to have questions/answers randomly mixed.
Sorry.My bad.
Thanks for the answer. You gave me clarity as to which approach of my code will work and also cleared my doubts.
Cheers :)