Hi, I am trying to communicate SSP on 2 LPC23xx boards. One is Master and other is Slave. Master Board Sending data correctly but Slave Board is not receiving data.
Please help...or send Slave mode code ...initialization of SSP Slave is According to Datasheet.
Thank You
Dear sir, Thanku for ur response,i write code according to datasheet and again i studied datasheet with ur suggestion but slave response is not coming. slave only receiving
for master i put DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 7 for slave DSS data to 8-bit, Frame format SPI, CPOL = 1, CPHA = 1, and SCR is 7
when slave sending response its waiting for busy bit forever;
Thank you
I would expect that the master and slave use the same clock polarity...?
i tried all combinations ...
here master CPOL = 0, CPHA = 0 for slave CPOL = 1, CPHA = 1 working master- slave data transfer
and master CPOL = 1, CPHA = 0 for slave CPOL = 0, CPHA = 1 working master- slave data transfer
other not working and my problem is at least no pluses coming on MISO
I'm not sure how we can help you.
1) You haven't written that you have started to use the slave select signal as it is expected to be used. Having it grounded on the slave is not a correct use. SSEL is not just an enable. It is also the method the slave uses to make sure the bit counter is properly synchronized with the start of a transfer from the master - without SSEL toggling regularly, the slave will not get back in sync again if you lose a clock bit, or get some spurious noise in the clock signal.
2) You try to run slave and master with different settings - they should use the same for phase and polarity.
3) You haven't told us anything about how you have initialized the slave, or what the slave code looks like. Or if you have mapped all four signals from GPIO into their hard-coded functionality for SPI communication.
4) You claim master->slave communiation works, but have given us zero information about what happens on the MISO signal - is it floating? Is the slave driving it constantly low? Is the slave driving it constantly high? Is it sending out data, but the master picks up something different from what the slave did try to send (happens if slave has lost sync and you refuse to use the SSEL signal).
5) You haven't mentioned anything about what debugging you have tried. What you have seen. What you expected to see. What your beliefs are, based on the differences between what you saw and what you expected to see.
We shouldn't have to drag information out of you. That is just information given to us, that you are not too interested in putting some effort into getting this problem solved. So the message must then be that we shouldn't be too interested in helping either.
By the way - where in the manual did you see information that recommended that you should run master and slave with different settings? Or was that just a "let's do some random tests?"
Master init:
void SSP1Handler (void) __irq { IENABLE; if ( SSP1MIS & SSPMIS_RORMIS ){ // Receive overrun interrupt SSP1ICR = SSPICR_RORIC; // clear interrupt } if ( SSP1MIS & SSPMIS_RTMIS ){ // Receive timeout interrupt f_ssp_rx=1; SSP1ICR = SSPICR_RTIC; // clear interrupt } if ( SSP1MIS & SSPMIS_RXMIS ){ // Rx at least half full f_ssp_rx=1; } if(f_ssp_rx == 1){ f_ssp_rx = 0; IOCLR0 |= 0x00000040; SSP1_Receive(); IOSET0 |= 0x00000040; } IDISABLE; VICVectAddr = 0; // Acknowledge Interrupt } /***************************************************************************** ** Function name: SSP1Init ** ** Descriptions: SSP1 port initialization routine ** ** parameters: None ** Returned value: true or false, if the interrupt handler ** can't be installed correctly, return false. ** *****************************************************************************/ void SSP1_Init( uint8_t mode ){ BYTE i, Dummy=Dummy; PCONP |= (1 << 10); PINSEL0 |= 0x000AA000; // port 0 bits 7, 8, 9, 6 are SSP port SCK1,MISO1,MOSI1,andSSEL1 IODIR0 |= 0x00000040; IOCLR0 |= 0x00000040; SSP1CR0 = 0x0747; // Set DSS data to 8-bit, Frame format SPI, CPOL = 1, CPHA = 0, and SSP1CPSR = 0x2; //SSPCPSR clock prescale register, master mode, minimum divisor for ( i = 0; i < FIFOSIZE; i++ ){ Dummy = SSP1DR; // clear the RxFIFO } //SSP1IMSC=0; install_irq( SSP1_INT, (void *)SSP1Handler, HIGHEST_PRIORITY ); if(mode==1){ // The SSP controller acts as a slave on the bus SSP1CR1 |= SSPCR1_MS; //SSP1CR1 |= 0x06; // ssp enable, ssp1 selects as Slave } else SSP1CR1 |= SSPCR1_SSE; // ssp enable, ssp1 selects as master SSP1CR1 |= SSPCR1_SSE; /* Enable SSP */ SSP1IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM ;// Set SSPINMS registers to enable interrupts LVDS_TX_EN_SET(); }
slave init:
/***************************************************************************** ** Function name: SSP1Init ** ** Descriptions: SSP1 port initialization routine ** ** parameters: None ** Returned value: true or false, if the interrupt handler ** can't be installed correctly, return false. ** *****************************************************************************/ void SSP1_Init( uint8_t mode ){ uint32_t i, Dummy=Dummy; SSP1CR1 = 0; PCONP |= (1 << 10); //PINSEL0 &= ~(0x000A8000); PINSEL0 |= 0x000AA000;// port 0 bits 7, 8, 9, 6 are SSP port SCK1, MISO1, MOSI1,ssel1 SSP1CR0 = 0x0787;// Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 1, and SSP1CPSR = 0x2; for ( i = 0; i < FIFOSIZE; i++ ){ Dummy = SSP1DR; // clear the RxFIFO } SSP1IMSC=0; install_irq( SSP1_INT, (void *)SSP1Handler, HIGHEST_PRIORITY ); if(mode==1){ SSP1CR1 |= SSPCR1_MS; } else SSP1CR1 &=~( SSPCR1_MS); // ssp enable, ssp1 selects as master SSP1CR1 |= SSPCR1_SSE; SSP1IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM ;// Set SSPINMS registers to enable interrupts LVDS_TX_EN_SET(); }
Dear sir,
1.In my PCB we are not using chip select pin...Bcoz master sends frame with slave address
2.I tried all phase and polarity ...
4.MISO always high there is no change in MISO...slave is not sending data.and clock also not generating on slave response.
1) In your PCB you royally fucked up, because you didn't read up on SPI before you designed the hardware. Bring in the solder iron and fix your PCB. You want a slave-select signal to your slave. You do not want the slave select signal hard-coded.
Or give me 10 sentences describing your code to let master and slave receivers analyze the bit streams on a bit-by-bit basis to figure out how to synchronize the data into bytes in case there have been an extra clock bit detected by the slave. In asynchronous serial communication, the UART makes use of the start bit as a signal when to start counting the individual bits in a transmitted byte. With SPI, it's the slave-select signal that aligns the slave-side bit counter so the slave picks up data 8 bit at the time at the same separation as the master sends out the data 8 bit at a time.
When you don't have the slave select to synchronize, you need something else. HDLC makes use of special start patterns that are forbidden in the actual data stream, to be able to pick up the exact bit that represents the start of a message.
2) Isn't it a bit silly to try all phases and polarities? All four combinations works, when master and slave are using the same setting. When connecting to a device someone else have designed, you need to find out which of the combinations to use. When you design both sides, you can decide yourself which one to use.
3) MSIO always high?
4) You have a function with a big and impressive comment header documenting everything important about your function. Or does it? Your claim: ** parameters: None So why then a function looking like: void SSP1_Init( uint8_t mode );
Does mode really look like a non-existing parameter?
Next thing - what is mode?
if(mode==1){ // The SSP controller acts as a slave on the bus
So you use it to select master or slave. Why didn't you then use the name "is_slave" or similar, so someone who sees the parameter name understands the difference between giving it a zero or non-zero value?
5) Note that the data direction settings are GPIO settings. But when you change the PINSEL configuration from GPIO to SSP, the pins are no longer GPIO. So they will not care about GPIO settings.
6)
SSP1IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM ;// Set SSPINMS registers to enable interrupts
You select RORIM - receive overflow (loss of data from full FIFO) You select RTIM - receive timeout (data in receive FIFO but doesn't seem to get more data) Why not RXIM - receiev FIFO is at least half-full Why not TXIM - transmit FIFO is at least half-empty
So you don't want an interrupt when you get data? You want an interrupt first when your slave have to start to throw away data because you haven't been emptying the FIFO in time? Is that a good policy?
7)
if ( SSP1MIS & SSPMIS_RORMIS ){ // Receive overrun interrupt SSP1ICR = SSPICR_RORIC; // clear interrupt }
When the slave reports that the FIFO is full and it has started to throw away data, you decide to just ignore. Why? Don't you realize that you have a full FIFO with data waiting? How do you expect this FIFO to ever be emptied? Wait until your master stops sending so you get a RTIM - receive FIFO timeout?
Why do you want a lossy transfer link, that only starts to pick up received data (after potentiall loss of an unknown amount of data) after the master have stopped the transfer? You only want the tail of large messages?
8) Don't you want at least the master to care about TXIM, to fill the transmit FIFO with more data?
9) SSP1_Receive(); What does it do? Does it contain any transmit code? Who else is giving the SPI (either side) something to send? SPI is always two-way. You can disable the MISO signal of a slave to just listen. But if you expect it to send back any answer, you must have code somewhere that feeds data to the SSP controller.
Dear sir, i know SPI protocol and i did 2 projects on spi one is 10'inch LCD interfacing with IMAX controller and atmel sam7s controller sussesfully.
now here in my new project we have 48 slave boards and 1 master board.and i have choice of only 1 master chip select pin...
so for all slave SSEL pins are directly grounded. and i need above 50MBPS speed so here i am using LVDS in middle of slaves and master.
now with ur suggestion i am using SSEL1 pin for slave now i am getting full duplex data its fine but problem is master is not taking MISO data
here i am using for master CPOL=0,CPHA=0 for slave CPOL=1,CPOL=1
Thanku
But you could have connected that single master pin to every slave, in case you don't need two-way communication.
Or if you do need data from slaves, you use an additional gate and a couple of GPIO pins to specify an address, making sure that only one slave gets the enable signal.
You are basically building an elevator without sensors for floor position and top/bottom position. Then you let the elevator motor just count time to try to figure out if it is getting close to third or fourth floor, totally without feedback for error correction.
A SPI slave can work with constantly enabled slave select. But one single pulse extra or lost means it will be one bit off until you reset the controller or you deactivate/reactivate the slave-select signal. What mechanics do you have to get your slaves to know when to reset the SPI controller, since you obviously can't toggle the slave select input?
Where did you find the recommendation to use:
One side should send out data rising clock and sample incomming data on falling clock. The other side should send out data on falling clock, and sample incomming data on rising clock. Is that what you want?
Polarity and phase are important. Sampling the data on the wrong phase is a catastrophe, depending on what extra delays you have introduced in the transfer channel. If you don't have the required setup and hold times, you don't know what data the master or the slave or both of them will sample. Your LVDS chips might potentially delay your signals a bit, but have you verified how much it delays the signals, in relation to the cycle time of your 50MHz clock signal?
Another thing: If you send data to 48 slaves, all of them can hear the signal. But the 48 slaves will want to send data back at the same time, unless you explicitly change back that data signal into a tristated GPIO signal. So with all 48 slave-select inputs hard-coded - what do you use to select which of the slaves that will get any data routed into the MISO pin of the master?
You complain your master isn't receiving any data. But why should it? You have asked it not to. Unless, there is a timeout. But there will only be a timeout if you stop the master from sending. Or you deactivate all your slaves in some way.
Your main problem is: It doesn't work. That is a very strong indication that you need to backtrack a bit, and reconsider your assumptions. You have lots of things to think about. Every little assumption you have made should be matched to measurements and manual paragraphs.
Things like: do you want interrupts when you have data available? Or do you wait until you get a timeout or an overflow? How does your overflows affect your communication? Do you have the required settle and hold times? How does the slaves readjust to get into sync again if they get a spurious clock pulse? Or if one of them get a watchdog reset? How do you decide which slave data line will reach the master? And how do you make sure that the other 47 slaves does not destroy this signal?