Using USB-Host and SPI (SSP0) at the same time

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Using USB-Host and SPI (SSP0) at the same time

3,629件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by HeinrichG on Tue Jan 03 17:00:47 MST 2012
Hello,

I would like to steam MP3 from USB-Stick to VS1053b connected to SPI (over SSP0-Block). It seems to run, but I have some breaks in the song (MP3-file from USB-stick).

My MCU is LPC1768 with 12MHz Clock.

Here is PLL-Init routine:

// Initializing the clocks of LPC1768:
void PLL_Init(void)
{
    LPC_SC->SCS       = SCS_Val;
    if (SCS_Val & (1 << 5))
    {
        while ((LPC_SC->SCS & (1<<6)) == 0);
    }

    LPC_SC->CCLKCFG   = CCLKCFG_Val;

    if (PLL0_SETUP)
    {
        LPC_SC->CLKSRCSEL = CLKSRCSEL_Val;
        LPC_SC->PLL0CFG   = PLL0CFG_Val;
        LPC_SC->PLL0CON   = 0x01;
        LPC_SC->PLL0FEED  = 0xAA;
        LPC_SC->PLL0FEED  = 0x55;
        while (!(LPC_SC->PLL0STAT & (1<<26)));

        LPC_SC->PLL0CON   = 0x03;
        LPC_SC->PLL0FEED  = 0xAA;
        LPC_SC->PLL0FEED  = 0x55;
    }

    if (PLL1_SETUP)
    {
        LPC_SC->PLL1CFG   = PLL1CFG_Val;
        LPC_SC->PLL1CON   = 0x01;
        LPC_SC->PLL1FEED  = 0xAA;
        LPC_SC->PLL1FEED  = 0x55;
        while (!(LPC_SC->PLL1STAT & (1<<10)));

        LPC_SC->PLL1CON   = 0x03;
        LPC_SC->PLL1FEED  = 0xAA;
        LPC_SC->PLL1FEED  = 0x55;
    }
    else

        LPC_SC->USBCLKCFG = USBCLKCFG_Val;
}


Here is Init-routine for SPI:

void SPI_Init (void) {
    /* Enable SSPI0 block */
    LPC_SC->PCONP |= (1 << 21);

    /* Set SSEL0 as GPIO, output high */
    LPC_PINCON->PINSEL1 &= ~(3 << 0);          /* Configure P0.16(SSEL) as GPIO */
    LPC_GPIO0->FIODIR |= (1 << 16);            /* set P0.16 as output */

    /* Configure other SSP pins: SCK, MISO, MOSI */
    LPC_PINCON->PINSEL0 &= ~(3UL << 30);
    LPC_PINCON->PINSEL0 |=  (2UL << 30);          /* P0.15: SCK0 */
    LPC_PINCON->PINSEL1 &= ~((3<<2) | (3<<4));
    LPC_PINCON->PINSEL1 |=  ((2<<2) | (2<<4));  /* P0.17: MISO0, P0.18: MOSI0 */

    /* Configure SSP0_PCLK to CCLK(100MHz), default value is CCLK/4 */
    LPC_SC->PCLKSEL1 &= ~(3 << 10);
    LPC_SC->PCLKSEL1 |=  (1 << 10);  /* SSP0_PCLK=CCLK */

    /* 8bit, SPI frame format, CPOL=0, CPHA=0, SCR=0 */
    LPC_SSP0->CR0 = (0x07 << 0) |     /* data width: 8bit*/
                    (0x00 << 4) |     /* frame format: SPI */
                    (0x00 << 6) |     /* CPOL: low level */
                    (0x00 << 7) |     /* CPHA: first edge */
                    (0x00 << 8);      /* SCR = 0 */

    /* Enable SSP0 as a master */
    LPC_SSP0->CR1 = (0x00 << 0) |   /* Normal mode */
                    (0x01 << 1) |   /* Enable SSP0 */
                    (0x00 << 2) |   /* Master */
                    (0x00 << 3);    /* slave output disabled */

    /* Configure SSP0 clock rate to 400kHz (100MHz/250) */
    SPI_ConfigClockRate (SPI_CLOCKRATE_LOW);
}


SPI_ConfigClockRate:

void SPI_ConfigClockRate (uint32_t SPI_CLOCKRATE)
{
    /* CPSR must be an even value between 2 and 254 */
    LPC_SSP0->CPSR = (SPI_CLOCKRATE & 0xFE);
}


I've connected my logic analyzer and I seen a strange picture, the picture is attached.

Any ideas what is wrong?

Many thanks & kind regards,
Heinrich
0 件の賞賛
返信
19 返答(返信)

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Jan 11 09:48:17 MST 2012

Quote:
SPI in this example was running with 100/26 = 3,8MHz and sapmle rate of analyzer was 4MHz.

Reading 3.8MHz with 4MHz, that's nearly Oversampling  :rolleyes::rolleyes:


Quote:
But I think 5ms for 512byte over USB is a bit slow, isn't it?

So the rest of the world is reading SD (25MHz SSP) within 1.2ms  ;)
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by HeinrichG on Wed Jan 11 02:04:06 MST 2012
Hmm, my logic analyzer is this one here: Overview and Specs

But I think 5ms for 512byte over USB is a bit slow, isn't it? It is just 100kB/sec.

SPI in this example was running with 100/26  = 3,8MHz and sapmle rate of analyzer was 4MHz. :(
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Jan 10 16:46:08 MST 2012

Quote: HeinrichG
SPI communication is a bit strange. There is a longer delay and the SPI clock is not really constant.

Any ideas?



Yes :eek: What you are showing us isn't possible, so you have to think about your logic analyzer toy. It's kidding you :p

If you want to see valid signals, use a faster tool or slow down SPI :eek:
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by HeinrichG on Tue Jan 10 16:18:51 MST 2012
So, I did some test.

First of all I checked what the SysTick doing. SysTick interrupt fires every 1ms. So, it is correct.

Here is a pic from logic analyzer (channel 7, bottom): click me

After that I checked how long MCU needs to read one block from usb-stick (512 bytes). It is exactly 5ms. Here is the pic of them (channel 7, bottom):

click me

After that I initialized SPI and copied 32 bytes to decoder:

click me

click me

click me

SPI communication is a bit strange. There is a longer delay and the SPI clock is not really constant.

Any ideas?

Sound plays a bit too fast (but not always) and choppy.

Actual code is here: click me

Thanks & regards,
Heinrich
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Jan 10 10:01:55 MST 2012

Quote: HeinrichG
Is it correct?



Yes, that's what you should also see if you scope SCLK :rolleyes:
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by HeinrichG on Tue Jan 10 09:46:10 MST 2012
Okay, so my CCLK s running with 100MHz.

In SSP0-init routine I set PCLK_SSP0 to 100MHz (divider = 1)

LPC_SC->PCLKSEL1 &= ~(3 << 10); 
LPC_SC->PCLKSEL1 |=  (1 << 10);  /* SSP0_PCLK=CCLK */


So, my SSP0 is running with 100MHz.

After that I set the divider for SPP0 clock rate with:
LPC_SSP0->CPSR = (SPI_CLOCKRATE & 0xFE);


This set SPP0 clock rate, i.e. SPI_CLOCKRATE = 20, I'll get 100MHz / 20 = 400kHz or SPI_CLOCKRATE = 7, I'll get 100MHz / 6 (because of 0xFE) = 16,666MHz.

Is it correct?

Thanks & regards,
Heinrich
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Jan 10 04:14:23 MST 2012

Quote: HeinrichG

Is it correct?



Yes :)
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by HeinrichG on Tue Jan 10 04:06:02 MST 2012
Sorry for a late answer.

Yesterday I did some changes in my code (not commited yet), so I read a 512 ybte block from usb and then stream them to VS1053 in 32 byte portions. But behavior is the same

Today I will connect my logic analyzer to spi and check what is happening on the bus (SCLK, DREQ, MOSI). I guesss, it is something strange with clock of spi or something like them. Yesterday I used the unmodified SystemInit() routine from CMSISv2p00_LPC17xx. The settings are following:

#define CLOCK_SETUP           1
#define SCS_Val               0x00000020
#define CLKSRCSEL_Val         0x00000001
#define PLL0_SETUP            1
#define PLL0CFG_Val           0x00050063
#define PLL1_SETUP            1
#define PLL1CFG_Val           0x00000023
#define CCLKCFG_Val           0x00000003
#define USBCLKCFG_Val         0x00000000
#define PCLKSEL0_Val          0x00000000
#define PCLKSEL1_Val          0x00000000
#define PCONP_Val             0x042887DE
#define CLKOUTCFG_Val         0x00000000


That means:
-> use Quarz
-> M = 100
-> N = 6
-> Fcco = 400MHz
-> CPUfreq = 100MHz
-> PLL1 with 48MHz
-> CCLK = PLLCLK / 4 = 100MHz

Is it correct?

Thanks & regards,
Heinrich
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Jan 06 08:03:38 MST 2012
To avoid more confusion about this issue I've resurrected a good old VS1001K (found it in my "1001 toys / 2003" :eek: box).

Plugged it in a LPCXpresso1769 and it's working without problems

unsigned char buf[512];                    //buffer
unsigned char* data_buffer;                //pointer to data buffer 

if(file_fopen(&filer,&(efs.myFs),(char*)filename[play_num],MODE_READ)== 0)
{
 printf("File opened with %d\n",filer.FileSize);
 while((e=file_read(&filer,512,buf)))//reading 512 bytes
 {
  data_buffer = &buf[0];            //set pointer to start of 512 bytes
  for (f=0;f<e;f+=32)
  {
      vs1063_write32Byte();            //pump them down in 32 byte blocks    
  }
 }
 file_fclose(&filer);
 printf("\n->End of File\n");
}
with
//write 32 bytes from buffer
void vs1063_write32Byte (void)
{
 XDCS_SELECT();                    //set XDCS
 while (!DREQ_STATUS());        //low while VS10xx buffer is full 
 unsigned char i = 0;
 for (i = 0; i < 32; i++)
 {
  SPI_SendByte(*data_buffer++); //send 32 bytes and inc buffer
 }
 XDCS_DESELECT();                //clear XDCS
}
Video:

http://youtu.be/k0hlpbS6XyQ

What are we seeing here?

#1 The [B][COLOR=Blue]blue signal[/COLOR][/B] is DREQ = VS1001 is crying for data (if high).

#2 The [B][COLOR=Yellow]yellow signal[/COLOR][/B] is SCLK from SSP, streaming data from LPC1769 to VS1001.

#3 The black part in SCLK signal is the time needed to reload another 512byte buffer from SD, so this delays the process about 1ms.

#4 If no SD reading is done, the streaming process needs about 1350µs.

#5 Maths: With 4MHz SSP 32 bytes are transmitted in 106µs, so we are seeing about 13 block of 32 bytes are transmitted.
That's repeated every 26ms = 38 times per second. So we get 32 * 13 * 38 * 60 = 950 kbyte/min. My mp3 file plays 4 min with 3770kbyte :rolleyes:

Although this is an VS1001 and no VS1053 the basic mechanism is the same
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Wed Jan 04 10:53:30 MST 2012

Quote:
How can I test it?



Duh ... you have a logic analyzer don't you.
Just place some instructions to toggle a GPIO around your f_read and you know what time it takes to read the data.

Did you use any DMA for SD and/or SSP?
I'm sure that you will see hickups in the data when not using DMA.

Regards,[INDENT]Rob
[/INDENT]
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Jan 04 10:26:17 MST 2012
You have to figure out what is and what is not transmitted. Your unreadable picture showed an SPI communication?

So you can measure how many bytes are transmitted and if it's a buffer problem

Also you can try to increase your reading buffer:

rc1 = f_read(&file1, buffer, sizeof(buffer), &br);
Read 2048 instead of 32 bytes and see if there's a difference :rolleyes:

Isn't there a 2048 bytes FIFO in there? So fill this buffer and you gain a little bit time to read the next data from file
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by HeinrichG on Wed Jan 04 09:31:58 MST 2012
During the initialisation is SPP speed set to 400kHz, after that to 5MHz.

I'm using my own code to control VS1053.

If you want, check this out. It's my own SVN-repository with this project: click me
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Jan 04 07:51:10 MST 2012

Quote: HeinrichG
SSP is running with:

LOW: 400kHz, divider 250
HIGH: 5MHz, divider 20

The decoder allows up to 12MHz.



The question is how fast your SSP is communicating with the decoder?

Is it 400KHz, 5MHz, 12MHz?

Which code are you using? Did you read something like

http://mbed.org/users/christi_s/libraries/VS1053b/ll30y4
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Wed Jan 04 00:17:09 MST 2012
Are you sure it's the SSP that is responsible for the hickups ?
How fast does the data from your USB stick arrive?

If USB delays then there is no data to send to the SSP and your clock will stop (as seen in your picture).

Rob
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Jan 03 18:50:20 MST 2012
And your SSP is running with which speed?

How fast is the allowed speed for your decoder?
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by HeinrichG on Tue Jan 03 18:35:58 MST 2012
So, now I've tried with following settings:
M=100
N=6
Fcco=400MHz
CCLK-Div= 4, so CCLK is 100MHz

The problem is the same :(
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Jan 03 18:26:41 MST 2012

Quote:

                      CCLK is 12MHz.

What  :eek:

With 12MHz crystal and PLL0CFG_Val of 11 your FCCO should be 288MHz.

With CCLKCFG_Val = 23 you are using PLL to generate 12MHz CCLK.

#1 Why are you using PLL ?

#2 How do you generate 25MHz from CCLK = 12MHz ?

That's a new mathematic for me: 12 /4 = 25 :rolleyes: The sample you are using is made for a 100MHz CCLK :eek:

Can't read your 397 x 280 pixel picture, but I would suggest to use higher CCLK and measure your real SSP signal :)
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by HeinrichG on Tue Jan 03 17:34:02 MST 2012
CCLK is 12MHz.

SSP_Low_Speed is 400kHz (divider 250)
SSP_High_Speed is 25MHz (divider 4)

Here are register definitions:

#define SCS_Val0x20
#define CLKSRCSEL_Val0x1
#define PLL0_SETUP0x1
#define PLL0CFG_Val0xb
#define CCLKCFG_Val0x17
#define PLL1_SETUP0x1
#define PLL1CFG_Val0x23
#define USBCLKCFG_Val0x5


Thanks & regards,
Heinrich
0 件の賞賛
返信

3,588件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Jan 03 17:10:12 MST 2012
First question is what CCLK you are using and which SSP speed you are trying to run :confused:
0 件の賞賛
返信