SSP sending out data 7.5 bits behind, LPC1114

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

SSP sending out data 7.5 bits behind, LPC1114

771 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by coryrc on Wed May 11 17:15:56 MST 2011
Hi,

I have a very weird problem with SSP in SPI mode, CPHA/CPOL == 0.

Data seems to usually come out 7.5 or 8.5 bits after they are supposed to. The data is being changed on the up clock instead of the down clock, regardless of the CPHA/CPOL settings. I am only sending 8 bits at a time. When I send out a byte, the previous byte that was written to LPC_SSP0->DR appears on the output! I know this for sure because I put my oscilloscope on clock and data, then breakpoint on LPC_SSP0->DR = *buf. I see *buf equals say, 0x6. I'll do one step and the last thing written pops out! I go through again, and next time 0x6 will pop out instead of what's being written that time. This also happens free-running as well.

If I set it to 16 bit mode, everything is shifted only 8 bits backward (so the upper 8 bits are the lower 8 bits of the previous transmission) instead of 16 bits, as you might expect if there was some TXFIFO issue of some sort.

Sometimes after a compile/debug it starts working for a little while, but if I remove power and reapply it stops working. I've tried two different boards (both LPC1114/301). Here's my SSP setup:
  LPC_SYSCON->PRESETCTRL |= (0x1<<0);
    LPC_SYSCON->SYSAHBCLKCTRL |= (0x1<<11);
    LPC_SYSCON->SSP0CLKDIV = 0x06;            /* Divided by 6 */
  LPC_IOCON->PIO0_8           &= ~0x07;    /*  SSP I/O config */
  LPC_IOCON->PIO0_8           |= 0x01;        /* SSP MISO */
  LPC_IOCON->PIO0_9           &= ~0x07;
  LPC_IOCON->PIO0_9           |= 0x01;        /* SSP MOSI */

    LPC_IOCON->SCK_LOC = 0x02;
    LPC_IOCON->PIO0_6 = 0xD2;

  /* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 7 */
    LPC_SSP0->CR0 = 0x0707;

  /* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */
    LPC_SSP0->CPSR = 0x2;

  /* Master mode */
    LPC_SSP0->CR1 = 0;
    LPC_SSP0->CR1 = SSPCR1_SSE;
For sending, I do:

  for ( i = 0; i < Length; i++ ) {
    /* Move on only if TX FIFO not full. */
      while ( (LPC_SSP0->SR & SSPSR_TNF) != SSPSR_TNF );
      LPC_SSP0->DR = *buf;
      buf++;
  }
    /* Wait until the Busy bit is cleared. */
  while ( LPC_SSP0->SR & SSPSR_BSY );


I'm running 12Mhz system clock (direct from IRC) and SPI clock is ~500kHz as measured.
Any guesses? Any ideas?
0 项奖励
回复
4 回复数

707 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu May 12 19:45:45 MST 2011
Yes, always blame the hardware guys....
0 项奖励
回复

707 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by coryrc on Thu May 12 19:24:39 MST 2011
I found the problem, same as the other guy I searched for and found he had the same problem:

I was measuring at the wrong point -- output of the shift register. When I would occasionally measure somewhere else it would work right...

This is a collaborative project so the other guy switched the input to be the output of another shift register and didn't tell me :(
0 项奖励
回复

707 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by coryrc on Thu May 12 15:29:55 MST 2011
Wow, Zero, thank you so much!


Quote: Zero
Can't confirm that:

1. Changing CPHA changes capturing as decribed in manual and as expected.

2. Your code is working, if you don't transmit Data too fast. Don't know why you've deleted the SSPSR_BSY check, but ignoring busy state doesn't make your code more reliable.



I took out the busy check because I intended to send data asynchronously without interrupts in the future, and I wanted to be able to queue up several bytes before running some other operations (16us*#bytes*send_rate adds up to a lot of time!)

But your confirmation that the setup code is correct is so helpful! Adding the busy check back in didn't help. I am going to make another project to test just the SPI functionality.
0 项奖励
回复

707 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu May 12 02:59:41 MST 2011
Can't confirm that:

1. Changing CPHA changes capturing as decribed in manual and as expected.

2. Your code is working, if you don't transmit Data too fast. Don't know why you've deleted the SSPSR_BSY check, but ignoring busy state doesn't make your code more reliable.

3. So my Serial Decoding Scope and Debugger are confirming that this code is working and data are transmitted correct

void spi_send(unsigned char* buf, unsigned int Length)
{
 unsigned int i;
 for ( i = 0; i < Length; i++ ) {
 while ( (LPC_SSP0->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF );
       LPC_SSP0->DR = *buf;
       buf++;
     }
}



The attached picture shows the same data buffer in scope and debugger after transmission:

http://www.flickr.com/photos/58892165@N08/5712320315/
0 项奖励
回复