Stop SPI "Framing" on LPC11C24

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

Stop SPI "Framing" on LPC11C24

1,706 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by brik2k on Tue Dec 25 21:48:59 MST 2012
Hi  everyone,
First, let me admit to being a little wet behind the ears here. I've just started playing around with the Xpresso board and the C programming language.

Anyway...on to my problem.  Long story short I'm trying to use the spi controller to accomplish a makeshift version of bit timing to control a ws2811 chip that does not use a clock signal. The problem is that the LPC spi controller seems to transmit the data in frames with a substantial delay between each frame. I've done quite a bit of searching and reading through the user manual and I'm unable to find any way remove the framing so the FIFO transmit bytes are sent in a continuous stream. Does anyone know if it's possible to get rid of the framing and the delay ? I do realize the framing/delay is not normally an issue for spi communication.

My code is below. It's a trimmed and modified version of the ssp example code. I've tried a number of register settings as well as taking out the busy and FIFO full checks.

Thanks for your help.


Name        : main.c
 Author      : 
 Version     :
 Copyright   : Copyright (C) 
 Description : main definition
===============================================================================
*/

#ifdef __USE_CMSIS
#include "LPC11xx.h"
#endif


/* SSP Status register */
#define SSPSR_TFE       (0x1<<0)
#define SSPSR_TNF       (0x1<<1)
#define SSPSR_RNE       (0x1<<2)
#define SSPSR_RFF       (0x1<<3)
#define SSPSR_BSY       (0x1<<4)

/* SSP CR0 register */
#define SSPCR0_DSS      (0x1<<0)
#define SSPCR0_FRF      (0x1<<4)
#define SSPCR0_SPO      (0x1<<6)
#define SSPCR0_SPH      (0x1<<7)
#define SSPCR0_SCR      (0x1<<8)

/* SSP CR1 register */
#define SSPCR1_LBM      (0x1<<0)
#define SSPCR1_SSE      (0x1<<1)
#define SSPCR1_MS       (0x1<<2)
#define SSPCR1_SOD      (0x1<<3)

/* SSP Interrupt Mask Set/Clear register */
#define SSPIMSC_RORIM   (0x1<<0)
#define SSPIMSC_RTIM    (0x1<<1)
#define SSPIMSC_RXIM    (0x1<<2)
#define SSPIMSC_TXIM    (0x1<<3)

/* SSP0 Interrupt Status register */
#define SSPRIS_RORRIS   (0x1<<0)
#define SSPRIS_RTRIS    (0x1<<1)
#define SSPRIS_RXRIS    (0x1<<2)
#define SSPRIS_TXRIS    (0x1<<3)

/* SSP0 Masked Interrupt register */
#define SSPMIS_RORMIS   (0x1<<0)
#define SSPMIS_RTMIS    (0x1<<1)
#define SSPMIS_RXMIS    (0x1<<2)
#define SSPMIS_TXMIS    (0x1<<3)

/* SSP0 Interrupt clear register */
#define SSPICR_RORIC    (0x1<<0)
#define SSPICR_RTIC     (0x1<<1)


/*****************************************************************************
** Function name:        SSP_IOConfig
**
** Descriptions:        SSP port initialization routine
**
** parameters:            None
** Returned value:        None
**
*****************************************************************************/
void SSP_IOConfig( uint8_t portNum )
{
  if ( portNum == 0 )
{
  LPC_SYSCON->PRESETCTRL |= (0x1<<0);
  LPC_SYSCON->SYSAHBCLKCTRL |= (0x1<<11);

  LPC_SYSCON->SSP0CLKDIV = 0x0A;            /* Divided by 2 */

  LPC_IOCON->PIO0_9           &= ~0x1f;
  LPC_IOCON->PIO0_9           |= 0x9;        /* SSP MOSI */

  }

  return;
}

/*****************************************************************************
** Function name:        SSP_Init
**
** Descriptions:        SSP port initialization routine
**
** parameters:            None
** Returned value:        None
**
*****************************************************************************/
void SSP_Init( uint8_t portNum )
{


  if ( portNum == 0 )
  {
  /* Set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 15 */
    LPC_SSP0->CR0 = 0x000F;

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


  /* Set SSPINMS registers to enable interrupts */
  /* enable all error related interrupts */
    LPC_SSP0->IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM;

     /* Device select as master, SSP Enabled */

      /* Master mode */
        LPC_SSP0->CR1 = SSPCR1_SSE;

  }

  return;
}

/*****************************************************************************
** Function name:        SSP_Send
**
** Descriptions:        Send a block of data to the SSP port, the
**                        first parameter is the buffer pointer, the 2nd
**                        parameter is the block length.
**
** parameters:            port #, buffer pointer, and the block length
** Returned value:        None
**
*****************************************************************************/
void SSP_Send(  )
{

     uint8_t Dummy = Dummy;

  while(1)
  {

    /* Move on only if NOT busy and TX FIFO not full. */
     while ( (LPC_SSP0->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF );



      LPC_SSP0->DR = 0xAA; //Manually coded output byte




      while ( (LPC_SSP0->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_SSP0->DR;

  }
  return;
}


/******************************************************************************
**   Main Function  main()
******************************************************************************/
int main (void)
{

    SSP_IOConfig(0);
    SSP_Init(0);

while (1)
{

  SSP_Send();

}
  return 0;
}

/******************************************************************************
**                            End Of File
******************************************************************************/

0 项奖励
回复
8 回复数

1,100 次查看
cctp
Contributor II

Sorry if it's bad form to resurrect an 8 year old thread, but this was still the first search result on google.

I ran into this issue on the S32k148 while working with WS2812s, and after poking around it seems the framing was being caused by overhead from operating in interrupt mode. Switching to DMA for SPI calls resolved the big pauses between SPI frames. I'm not even sure if that's an option for this chip, but for anyone else who has the same issue that was a the fix for this symptom on a different system.

0 项奖励
回复

1,524 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Dec 26 10:39:51 MST 2012

Quote:

I'm using 5 bit transfers resulting in a 100kHz bitrate. Unfortunately, when I turn up the clock to 4MHz...

That's 250ns at 4Mhz. With [COLOR=Red]5 bit[/COLOR] you can generate 250, 500, 750, 1000, 1250 ns signals ;)

Datasheet talks about 1200 ns +/-150ns, that's 600ns +-75ns in high speed mode :eek:
0 项奖励
回复

1,524 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by brik2k on Wed Dec 26 10:05:15 MST 2012
Zero,
Thanks for pointing out the TI format! I thought Rob's response meant that he had tried it with no luck but I went ahead and tried it anyway.

With the spi set to TI it appears the framing delay is gone, at least on my cheap DS Nano scope. At a test rate of 500kHz things look pretty good. I'm using 5 bit transfers resulting in a 100kHz bitrate. Unfortunately, when I turn up the clock to 4MHz, which would result in the required 800kHz for the w2811, the leds are not responding as expected and my Nano isn't fast enough to see what's actually happening. I guess it's time to invest in a real oscilloscope.
0 项奖励
回复

1,524 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Dec 26 08:09:13 MST 2012

Quote: brik2k
Either way, the problem is the delay between frames. If we could find a way to get rid of it the timing would be a simple enough thing to straighten out.



:confused:


Quote:
User manual is describing 'Texas Instruments Synchronous Serial Frame Format: Continuous/back-to-back Two Frames Transfer' :eek:

0 项奖励
回复

1,524 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by brik2k on Wed Dec 26 07:53:42 MST 2012
Here's a good page with some details on the chip. Apparently, there are at least two datasheets floating around with conflicting timing values.
http://bleaklow.com/2012/12/02/driving_the_ws2811_at_800khz_with_a_16mhz_avr.html

Either way, the problem is the delay between frames. If we could find a way to get rid of it the timing would be a simple enough thing to straighten out.

Have any of you guys played with the LPC11xx as a slave device on SPI? Does the spi controller respond on the MISO line with the same framing?
0 项奖励
回复

1,524 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Dec 26 06:38:58 MST 2012

Quote: Rob65
That does not work.
the ws2811 receives 24 bits with a precise bit timing. A one is sent as 1000 ns high and 250 ns low, a zero as 250 ns high and 1000 ns low.



:confused: Which WS2811 is that :confused:

ws2811.pdf:

Quote:

Low Speed mode time
T0H 0 code,high voltage time [COLOR=Red]0.5 &#956;s[/COLOR] ±150ns
T1H 1 code,high voltage time[COLOR=SeaGreen] 1.2 &#956;s[/COLOR] ±150ns
T0L 0 code,low voltage time [COLOR=Red]2.0 &#956;s[/COLOR] ±150ns
T1L 1 code,low voltage time [COLOR=SeaGreen]1.3 &#956;s[/COLOR] ±150ns
RES low voltage time Above 50&#956;s
Note: It is [COLOR=Red]one half of the time when high speed mode[/COLOR](reset time unchanged)

0 项奖励
回复

1,524 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Tue Dec 25 23:39:32 MST 2012
That does not work.
the ws2811 receives 24 bits with a precise bit timing. A one is sent as 1000 ns high and 250 ns low, a zero as 250 ns high and 1000 ns low.

To create such a precise bit timing using SPI he would (I guess) use 5 SPI bits for each ws2811 bit (11110 representing a one and 10000 a zero), needing a 120 bit frame.

Unfortunately I have not been able to completely remove the delay between the SPI words in my previous attempts.

Rob
0 项奖励
回复

1,524 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Dec 25 22:42:23 MST 2012

Quote: brik2k
... I've done quite a bit of searching and reading through the user manual and I'm unable to find any way remove the framing so the FIFO transmit bytes are sent in a continuous stream. Does anyone know if it's possible to get rid of the framing and the delay ?



User manual is describing 'Texas Instruments Synchronous Serial Frame Format: Continuous/back-to-back Two Frames Transfer' :eek:

So what about TI format and 2*12bit transfer ;)
0 项奖励
回复