We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have two question on SSP1 of LPC1768
1. We have configured SSP1 as TI SSI for receiving 16 bits of data. We have connected Sclk pin to Clock of salve and MISO pin to Data pin of Slave.We have generated clock to receive data from our slave. If i send the clock then SPDR value is getting updated but RNE bit is not set thus we are not able to read SPDr value. If we send the clock again my SPDR is always 0.
2. Can we read 18 bit data from the SSP1 which is configured as TI SSI with DSS as 9 bit and receiving SPDR value twice.
Code:
int main() { int j; SystemInit(); SSP1Init(); LPC_SSP1->DR=0x0000; SSPSend(1,0x0000,16); while(1) { } }
void SSP1Init( void ) { uint8_t i, Dummy=Dummy; LPC_SC->PCONP |= (0x1<<10);/* Enable AHB clock to the SSP1. */ LPC_SC->PCLKSEL0 &= ~(0x3<<20); /* P0.6~0.9 as SSP1 */ LPC_PINCON->PINSEL0 &= ~((0x3<<12)|(0x3<<16)|(0x3<<18)); LPC_PINCON->PINSEL0 |= ((0x2<<12)|(0x2<<16)|(0x2<<18)); /* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 15 */ LPC_SSP1->CR0 = 0x075F; /* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */ LPC_SSP1->CPSR = 0x2; for ( i = 0; i < FIFOSIZE; i++ ) { Dummy = LPC_SSP1->DR; /* clear the RxFIFO */ } NVIC_EnableIRQ(SSP1_IRQn); /* Enable the SSP Interrupt */ LPC_SSP1->CR1 = SSPCR1_SSE;/* Master mode *//* Device select as master, SSP Enabled */ /* Set SSPINMS registers to enable interrupts */ /* enable all error related interrupts */ LPC_SSP1->IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM; return; }
void SSPSend( uint32_t portnum, uint16_t buf) { uint32_t i; uint16_t Dummy = Dummy,receive[9]; if ( portnum == 1 ) { /* Move on only if NOT busy and TX FIFO not full. */ while ( (LPC_SSP1->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF ); LPC_SSP1->DR = buf; //buf++; #if !LOOPBACK_MODE while ( (LPC_SSP1->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE ); LPC_SSP1->DR=0x0000; receive[0] = LPC_SSP1->DR; #else /* Wait until the Busy bit is cleared. */ while ( LPC_SSP1->SR & SSPSR_BSY ); #endif } return; }
The chip has a FIFO. If you configure for 9-bit transfers then you need to perform two reads to pick up an 18-bit transfer and then merge the two reads into an 18-bit value in your own code.
But I don't understand your question since your sentences doesn't seem to agree with your code. You mentions TI SSI, but then your code contains a comment
/* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 15 */ LPC_SSP1->CR0 = 0x075F;
The assign seems to be a mixture between SPI and TI SSI.
Next thing here is that you talk about having connected 2 wires between processor and your slave device. For two-way communication you should have 4. But what about your FS signal?
Another thing is that if not in loopback mode you have two sends but one receive:
LPC_SSP1->DR = buf; <= send while ( (LPC_SSP1->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE ); LPC_SSP1->DR=0x0000; <= send receive[0] = LPC_SSP1->DR; <= receive
It is TI SSI communication only. We have initialized SSP as SSI. Its wrongly commented. Our slave has only 2 lines CLK and DAT. If i send 16 pulses then i receive 16 bit of data. We are not using FS and MOSI pins of the SSP1 block. If a 16 bit data is sent SPDR value is getting updated with the received bytes but RNE flag is low.We are not able to read the data from shift register.
Sp is there a reason why you don't want your comments to match your code?
/* P0.6~0.9 as SSP1 */ LPC_PINCON->PINSEL0 &= ~((0x3<<12)|(0x3<<16)|(0x3<<18)); LPC_PINCON->PINSEL0 |= ((0x2<<12)|(0x2<<16)|(0x2<<18));
You claim 4 pins are configured, but the code only configures 3.
/* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 15 */
You claim 8-bit but configure 16-bit. You claim SPI but configure TI. You claim CPOL and CPHA but they aren't applicable for TI.
You show a call in main looking like:
SSPSend(1,0x0000,16);
while you show an actual implementation looking like:
void SSPSend( uint32_t portnum, uint16_t buf)
Three parameters sent, and two received...
So lots of noise that tells a different story in the code. That doesn't really help.
And you still haven't explained your code doing two writes and one read. How do you expect to get a balance between receive FIFO and transmit FIFO with such code? In reality, you have three sends, since you start with writing a word in main() before you even call your send function.
You only use two signals. How is your external device then expected to find any frame synchronization to know when it's time for the most significant bit?
And your original post talks about an 18-bit transfer. But the TI protocol uses FS once for each transfer, so if the device expects an 18-bit transfer then it expects one clock pulse with FS and then 18 clock pulses for the data. Potentially with the last clock pulse having FS active again to indicate the start of yet another word transfer directly after the last bit of the previous word transfer.
Code with proper Comments :
int main (void) { uint32_t receive[18],buf=0x0000; SystemClockUpdate() updates the SystemFrequency variable SSP1Init(); //SSP Initialization SSPSend(1,0x0000,16); //dummy data=0x0000 to send 16-bit clock while(1) { } } void SSP1Init( void ) { uint8_t i, Dummy=Dummy; LPC_SC->PCONP |= (0x1<<10); //Enabling the SSP1 Clock /* Further divider is needed on SSP1 clock. Using default divided by 4 */ LPC_SC->PCLKSEL0 &= ~(0x3<<20); LPC_SC->PCLKSEL0 |= (0x3<<20); /* P0.6~0.9 as SSP1 */ LPC_PINCON->PINSEL0 &= ~((0x3<<12)|(0x3<<16)|(0x3<<18)|(0x3<<14)); //clear MISO and CLK LPC_PINCON->PINSEL0 |= ((0x2<<14)|(0x2<<16)); //set MISO1 and CLK1 pin functions /* Set DSS data to 16-bit, CPOL = 1, CPHA = 0, SSI mode and SCR is 7 */ LPC_SSP1->CR0 = 0x075F; /* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */ LPC_SSP1->CPSR = 0x02; { Dummy = LPC_SSP1->DR; /* clear the RxFIFO */ } NVIC_EnableIRQ(SSP1_IRQn); /* Enable the SSP Interrupt */ LPC_SSP1->CR1 = SSPCR1_SSE;/* Master mode *//* Device select as master, SSP Enabled */ /* Set SSPINMS registers to enable interrupts */ /* enable all error related interrupts */ LPC_SSP1->IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM; return; } void SSPSend( uint32_t portnum, int buf, uint32_t Length ) { uint32_t i; uint8_t Dummy ; for ( i = 0; i < Length; i++ ) { if ( portnum == 1 ) { /* Move on only if NOT busy and TX FIFO not full. */ while ( (LPC_SSP1->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF ); LPC_SSP1->DR = buf; #if !LOOPBACK_MODE while ( (LPC_SSP1->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE ); /* Whenever a byte is written, MISO FIFO counter increments, Clear FIFO on MISO. Otherwise, when SSP0Receive() is called, previous data byte is left in the FIFO. */ Dummy = LPC_SSP1->DR; //equating the SPDR to Dummy Varaible #else /* Wait until the Busy bit is cleared. */ while ( LPC_SSP1->SR & SSPSR_BSY ); #endif } } return ; }
.
Please go through the link below for the slave details which is being interfaced with the controller.We are using a line driver Ic(part No: MAX3079) between the slave and master controller to convert the differential to single line pulses.
www.netzerprecision.com/.../DS-58-32-02-V2.0a.pdf
Can you please give us your Skype Id .
"Can you please give us your Skype Id"
Amazing. Plain and simple.
http://www.keil.com/forum/22059/
Updated comments?
/* P0.6~0.9 as SSP1 */ LPC_PINCON->PINSEL0 &= ~((0x3<<12)|(0x3<<16)|(0x3<<18)|(0x3<<14)); //clear MISO and CLK LPC_PINCON->PINSEL0 |= ((0x2<<14)|(0x2<<16)); //set MISO1 and CLK1 pin functions /* Set DSS data to 16-bit, CPOL = 1, CPHA = 0, SSI mode and SCR is 7 */ LPC_SSP1->CR0 = 0x075F;
Why does the comment say that you are configuring P0.6 to P0.9 (4 pins) for SSP1, when you clear the configuration bits for 4 pins and then sets the bits for 2 pins?
And what does CPOL=1 or CPHA=0 have to do with SSI? They are for SPI mode.
/* Whenever a byte is written, MISO FIFO counter increments, Clear FIFO on MISO. Otherwise, when SSP0Receive() is called, previous data byte is left in the FIFO. */ Dummy = LPC_SSP1->DR; //equating the SPDR to Dummy Varaible
But you have a sensor connected that only sends data to your processor. So it's the write that is a "dummy" to generate clock toggles. The read isn't a dummy. How can your comment then include a description how you need to clear your FIFO on MISO? You don't even seem to have any SSP0Receive(). You really sure you did update the comments to actually agree with what the code does - or is expected to do?
You configure for TI SSI.
But your device don't mention any TI SSI. Only SSi (which is just the generic term Synchronous Serial Interface).
TI SSI clocks in data on falling clock edge. Emits data in rising edge. Your sensor seems to use the reverse. Do you have an inverter on the clock?
TI SSI synchronizes using FS. Your sensor seems to synchronize by having a pause in the communication - where do you have any pause in your communication code for the monoflop to reset? You do a loop of 16 transfers as fast as the SSP can transfer data - does the datasheet for the sensor really seem to indicate that the sensor can handle that?
Your sensor have 18 bits (from what I deduce from your previous comments). There are no information in the datasheet what it likes if you only do a 16-bit transfer. You should get out the 16 most significant bits. But does the sensor have extra issues with not being allowed to send the last two bits? Most probably not - if you allow time for the monoflop reset. Which you don't.
Are you giving this problem your full attention?
We don't have CLK inverter, instead we are doing that through CPOL (Setting High), though the data sheet of the controller recommends CLK to be Low for MISO configuration.
We were getting the values from the encoder but there were double the actual value ( with reference to the OEM Software Program)... we assumed that this was due to left shifting... hence we tried reading the data at the falling edge by changing the CPHA.
we have downgraded the encoder to 16 Bit --- excuse me, i didn't mention them in my previous posts.
The data are set to "buff" Register to generate the clock. then we are equating SPDR to "Dummy" Register for further processing.
Yes, I do know you need to write to the controller to force the clock pulses that results in the required read. My note was that you describe the _read_ as a dummy operation, indicating that it is the _write_ that is the real operation performed.
You didn't mention anything about the lack of delay in your code - how you make sure that the monoflop resets before next transfer, since that is the synchronization needed by the sensor to make sure it starts with sending out MSB and not continue to send the two least significant bits before starting with the 16 most significant bits of next read.
"hence we tried reading the data at the falling edge by changing the CPHA."
How? I have already two times notified you to CPHA being an SPI setting - but you don't configure SPI. You configure the TI mode.
From the manual: CPOL: "Clock Out Polarity. This bit is only used in SPI mode." CPHA: "Clock Out Phase. This bit is only used in SPI mode."
So in this case, the SPI mode would map better to your actual needs than trying the TI mode, if you want the CPOL and CPHA bits to actually mean anything.
Of course, differential signals would normally solve polarity by you switching Clock+ and Clock- unless you have already shipped the hardware and cabling.