SSP0 Receive problems

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SSP0 Receive problems

798 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Mauricio on Fri Jul 08 16:42:40 MST 2011
Hi,

I am trying to communicate with a flash memory, when I send data to the memory with SSP0 port the memory acknoledges it, but when I try to read the memory with a dummy byte the microcotroller cannot read it (I know that the memory is putting some data in the line after scoping it), but my LPC1768 doesn't update the DR register to what the memory sent.  The registers shown by the controller right before trying to read the byte are:

CR0 = 0x00001D07
CR1 = 0x00000002
DR = 0x000000FF
SR = 0x00000003
CPSR = 0x00000002
IMSC = 0x00000000
RIS = 0x00000008
MIS = 0x00000000
ICR = 0x00000000
DMACR = 0x00000000

I know that DR should be 0x00 before reading the port, but after reading the register with a dummy variable to clear the DR register with:

tmp = (uint32_t) SSP_ReceiveData(SSPx);

the DR doesn't clear, the (0xFF) is still there and the Status register doesn't reset as well. 

Am I missing any important step here (like clearing a flag) before reading the SSP0->DR?

Thanks
0 Kudos
9 Replies

646 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hamu on Thu Jul 14 05:12:53 MST 2011
Problem solved!!  Both pins are damaged :mad:. I had tried to use these pins as normal GPIO but they are also not working.

Sorry for my unnecessary questions!
0 Kudos

646 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hamu on Thu Jul 14 04:44:01 MST 2011
I have written in a former post that I´m using the LPC1114 - sorry again for this. So the code is the right one ;)

This is my whole code! Just this few lines. ...

[LEFT]int main (void)
{
uint8_t Buffer[2];

// init SSP0
SSP_IOConfig(0);[/LEFT]
SSP_Init(0);

// prepare buffer
Buffer[0] = 0xA;

// loop
while (1)
{
[SIZE=2][B]SSP_Send[/B]( 0[/SIZE][SIZE=2], &Buffer[/SIZE][SIZE=2], 1[/SIZE][SIZE=2]);[/SIZE]
delay(); // wait a little bit
}

If I use SSP1 with same code above it´s working.
0 Kudos

646 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Thu Jul 14 04:37:30 MST 2011
hamu,

Running lpc11xx code on an lpc1769 does not look that good to me :confused:
and if you only post a small section of your code then I'm sure the problem must be in the stuff you keep hidden from us :)


Rob
0 Kudos

646 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hamu on Thu Jul 14 04:36:06 MST 2011
Now I´m using the original driver functions from the example project (ssp.c, ssp.h).
In ssp.h all defines are 0...

[B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055][LEFT]#define[/B][/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] LOOPBACK_MODE 0 [/SIZE][SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f][/LEFT]
[/COLOR][/SIZE][/COLOR][/SIZE][B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055][LEFT]#define[/B][/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] SSP_SLAVE 0[/SIZE]
[SIZE=2] [/SIZE][B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055]#define[/B][/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] TX_RX_ONLY 0[/LEFT]
[/SIZE]
In my code I just use following lines:

[SIZE=2][LEFT]SSP_IOConfig(0);[/LEFT]
SSP_Init(0);

Buffer[0] = 0xA;
while (1)
{
[SIZE=2][B]    SSP_Send[/B]( 0[/SIZE][SIZE=2], &Buffer[/SIZE][SIZE=2], 1[/SIZE][SIZE=2]);[/SIZE]
    delay();   // wait a little bit
}
[SIZE=2][/SIZE]
[SIZE=2]The problem is still the same. There are no data on the MOSI pin (PIO0_9). The clock on PIO2_11 is correctly.[/SIZE]

I tried same code as above with SSP1 and all works correctly. So I don´t understand why the same code doesn´t work with SSP0  :confused:
[SIZE=2][/SIZE]
[SIZE=2]
[/SIZE]
[/SIZE]
0 Kudos

646 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu Jul 14 04:10:47 MST 2011

Quote: hamu
...[SIZE=2]what did i forget?? [/SIZE]



[LEFT]SSP_Init, LOOPBACK_MODE :confused:[/LEFT]

[LEFT]Could be a good idea to post your project.[/LEFT]
0 Kudos

646 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hamu on Thu Jul 14 03:36:08 MST 2011
Thanks for your code!
I have now checked my code again but I can´t find any error. In my last post I had forgotten that I have a LPC1114 but the problem is the same.

I have tried to send data out but it´s also not working - I can´t see data on the MOSI with the scope. If I use the loopback mode all works - so I assume that the SSP itself works but the pin configuration is buggy.

I use following code for the pin config:

[SIZE=2][LEFT]LPC_SYSCON->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]PRESETCTRL[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]            |= (0x1<<0);
LPC_SYSCON->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]SYSAHBCLKCTRL[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]  |= (0x1<<11);
LPC_SYSCON->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]SSP0CLKDIV[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]             = 0x02; [/SIZE][SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f]/* Divided by 2 */[/COLOR][/SIZE][/COLOR][/SIZE]
[SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f][/COLOR][/SIZE][/COLOR][/SIZE]
[SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f]/* SSP0 MISO */[/LEFT]
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][LEFT]LPC_IOCON->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]PIO0_8[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]                        &= ~0x07; [/SIZE]
[SIZE=2]LPC_IOCON->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]PIO0_8[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]                          |= 0x01; [/SIZE]
[SIZE=2][/SIZE]
[SIZE=2][COLOR=#3f7f5f]/* SSP0 MOSI */[/COLOR][/SIZE]
[SIZE=2]LPC_IOCON->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]PIO0_9[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]                        &= ~0x07;[/SIZE][SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f][/LEFT]
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][LEFT]LPC_IOCON->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]PIO0_9                        [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] |= 0x01;[/SIZE]
[SIZE=2][/SIZE]
[SIZE=2]/* SSP0 CLK */[/SIZE] [SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f][/LEFT]
[/COLOR][/SIZE][/COLOR][/SIZE][LEFT][SIZE=2]LPC_IOCON->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]SCK_LOC                   [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = 0x01;
LPC_IOCON->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]PIO2_11                      [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = 0x01; [/SIZE][SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f]/* P2.11 function 1 is SSP clock,[/LEFT]
[/COLOR][/SIZE][/COLOR][/SIZE][B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055][LEFT]
[COLOR=#3f7f5f]/* SSP SSEL is a GPIO pin */[SIZE=2][SIZE=2][/SIZE][/SIZE][/COLOR][/B][/COLOR][/SIZE][/COLOR][/SIZE][LEFT][SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f][/LEFT]
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]LPC_SYSCON->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]SYSAHBCLKCTRL[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] |= (1<<6);

LPC_IOCON->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]PIO0_2[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] &= ~0x07; [/SIZE]
[SIZE=2]GPIOSetDir( PORT0, 2, 1 );
GPIOSetValue( PORT0, 2, 1 );

What is wrong or what did i forget?? Only the SSP0 CLK pin is working correctly :mad:

Thanks![/LEFT]
[/SIZE][LEFT][SIZE=2] [/LEFT]
[/SIZE]
0 Kudos

646 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Wed Jul 13 13:14:22 MST 2011
If it helps,

here is the code I use to have SSP1 talk to an SD card (using efsl):

/******************************************************************************
 * lpc_17xx_ssp1.c: interface functions to the lpc17xx SSP for EFSL
 *
 * Copyright (C) 2011, MyVoice
 * All Rights reserved.
 *
 * History
 * 2011.06.27    ver 1.00    Preliminary version, first release
 *
 * This file contains the interface functions needed by EFSL to access the
 * SD card via the SSP1 interface.
 *
 * This is based on te original lpc2000_spi.c file from EFSL
 *
 * Software License Agreement
 *
 * The software is owned by MyVoice CAD/CAM Services and/or its suppliers, and is
 * protected under applicable copyright laws.  All rights are reserved.  Any
 * use in violation of the foregoing restrictions may subject the user to criminal
 * sanctions under applicable laws, as well as to civil liability for the breach
 * of the terms and conditions of this license.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 * USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
 * TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
 * MYVOICE CAD/CAM SERVICES.
 *
 */

#include "LPC17xx.h"
#include "lpc17xx_ssp1.h"
#include "sd.h"
#include "config.h"
/*****************************************************************************/

// SP0SPCR  Bit-Definitions
#define CPHA    3
#define CPOL    4
#define MSTR    5
// SP0SPSR  Bit-Definitions
#define SR_BSY  4
#define SR_RNE  2

#define SPI_SCK_PIN             7        /* Clock        P0.15 out        (PINSEL0) */
#define SPI_SSEL_PIN         6        /* Card-Select    P0.16 GPIO out    (PINSEL1) */
#define SPI_MISO_PIN         8        /* from Card    P0.17 in        (PINSEL1) */
#define SPI_MOSI_PIN         9        /* to Card        P0.18 out        (PINSEL1) */

#define SPI_PINSEL            LPC_PINCON->PINSEL0
#define SPI_SCK_FUNCMASK    (3 << 14) // P0.7 - PINSEL0 [15:14]
#define SPI_SSEL_FUNCMASK    (3 << 12) // P0.6 - PINSEL0 [13:12]
#define SPI_MISO_FUNCMASK    (3 << 16) // P0.8 - PINSEL0 [17:16]
#define SPI_MOSI_FUNCMASK    (3 << 18) // P0.9 - PINSEL0 [19:18]

#define SPI_SCK_FUNCBIT        (2 << 14)
#define SPI_SSEL_FUNCBIT    (0 << 12) // Note - SSEL needed as GPIO
#define SPI_MISO_FUNCBIT    (2 << 16)
#define SPI_MOSI_FUNCBIT    (2 << 18)

#define SPI_PRESCALE_REG    LPC_SPI->SPCCR

#define SPI_PRESCALE_MIN  8

#define SELECT_CARD()   LPC_GPIO0->FIOCLR = (1 << SPI_SSEL_PIN)
#define UNSELECT_CARD() LPC_GPIO0->FIOSET = (1 << SPI_SSEL_PIN)


esint8 if_initInterface(hwInterface* file, eint8* opts)
{
    euint32 sc;
    
    if_spiInit(file); /* init at low speed */
    
    if(sd_Init(file)<0)    {
        DBG((TXT("Card failed to init, breaking up...\n")));
        return(-1);
    }
    if(sd_State(file)<0){
        DBG((TXT("Card didn't return the ready state, breaking up...\n")));
        return(-2);
    }
    
    sd_getDriveSize(file, &sc);
    file->sectorCount = sc/512;
    if( (sc%512) != 0) {
        file->sectorCount--;
    }
    DBG((TXT("Drive Size is %lu Bytes (%lu Sectors)\n"), sc, file->sectorCount));
    
    if_spiSetSpeed(SPI_PRESCALE_MIN);
    
    DBG((TXT("Init done...\n")));
    return(0);
}
/*****************************************************************************/ 

esint8 if_readBuf(hwInterface* file,euint32 address,euint8* buf)
{
    return(sd_readSector(file,address,buf,512));
}
/*****************************************************************************/

esint8 if_writeBuf(hwInterface* file,euint32 address,euint8* buf)
{
    return(sd_writeSector(file,address, buf));
}
/*****************************************************************************/ 

esint8 if_setPos(hwInterface* file,euint32 address)
{
    return(0);
}
/*****************************************************************************/ 

// Utility-functions which does not toggle CS.
// Only needed during card-init. During init
// the automatic chip-select is disabled for SSP

static euint8 my_if_spiSend(hwInterface *iface, euint8 outgoing)
{
    LPC_SSP1->DR = outgoing;
    while (LPC_SSP1->SR & (1 << SR_BSY));
    return LPC_SSP1->DR;
}
/*****************************************************************************/ 

void if_spiInit(hwInterface *iface)
{
    int i;

    DBG((TXT("spiInit for SSP(1)\n")));

    // Turn on the power
    LPC_SC->PCONP |= (1<<10); // PCSSP1

    // CodeRed - clock
    LPC_SC->PCLKSEL0 &= ~(3<<20);  // PCLK_SSP1
    LPC_SC->PCLKSEL0 |=  (1<<20);  // PCLK_periph = CCLK

    // setup GPIO
    LPC_GPIO0->FIODIR |= (1 << SPI_SCK_PIN) | (1 << SPI_MOSI_PIN) | (1 << SPI_SSEL_PIN);
    LPC_GPIO0->FIODIR &= ~(1 << SPI_MISO_PIN);

    /*
     * Set pin functions:
     *  P0.6 - SSEL1
     *  P0.7 - SCK1
     *  P0.8 - MISO1
     *  P0.9 - MOSI1
     */

    LPC_PINCON->PINSEL0 &= ~(SPI_SCK_FUNCMASK | SPI_MOSI_FUNCMASK | SPI_MISO_FUNCMASK | SPI_SSEL_FUNCMASK);
    LPC_PINCON->PINSEL0 |=  (SPI_SCK_FUNCBIT  | SPI_MOSI_FUNCBIT  | SPI_MISO_FUNCBIT  | SPI_SSEL_FUNCBIT );

    /*
     * enable SSP1-Master:
     *     8 bits
     *  CPHA = 0 (data is sampled on the first clock edge)
     *  CPOL = 0 9SCK is active high)
     *  Send data with MSB first
     */
    LPC_SSP1->CR0 = 0b00000111; /* CPHA = 0, CPOL = 0, FRF = 00, DSS = 0111 */
    LPC_SSP1->CR1 = 0b0010;     /* SOD = 0, MS = 0, SSE = 1, LBM = 0        */

    UNSELECT_CARD();


    /* Switch the SSP MOSI line to a GPIO and drive it high too. */
    //CRT - P0.9 back to GPIO
    // RWJ: ToDo: check!!!
    LPC_PINCON->PINSEL0 &= ~(SPI_MOSI_FUNCMASK);
    LPC_GPIO0->FIODIR |= (1<<SPI_MOSI_PIN);
    LPC_GPIO0->FIOSET = (1<<SPI_MOSI_PIN);

    // low speed during init
    if_spiSetSpeed(254);

    /* Send 21 spi commands with card not selected */
    for (i = 0; i < 21; i++) {
        my_if_spiSend(iface, 0xff);
    }


    LPC_PINCON->PINSEL0 |= (SPI_MOSI_FUNCBIT);

}

/*****************************************************************************/

void if_spiSetSpeed(euint8 speed)
{
    speed &= 0xFE;
    if (speed < SPI_PRESCALE_MIN) {
        speed = SPI_PRESCALE_MIN;
    }

    LPC_SSP1->CPSR = speed;
}

/*****************************************************************************/

euint8 if_spiSend(hwInterface *iface, euint8 outgoing)
{
    euint8 incoming;

    SELECT_CARD();
    LPC_SSP1->DR = outgoing;
    while(!(LPC_SSP1->SR & (1 << SR_RNE)));
    incoming = LPC_SSP1->DR;

    UNSELECT_CARD();

    return incoming;
}
/*****************************************************************************/

Of course you have to make sure that MOSI0 is connected to the correct pin using PINCON. MISO0 can be connected to either P0.17 or P1.23. If you programmed PINCON with the wrong pin then you won't read anything ...

Rob
0 Kudos

646 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hamu on Wed Jul 13 12:33:52 MST 2011
Hi,

I have the same problem as Mauricio! I just want to read only data from a ADC but DR is always empty.
I use following code:
.
.
LPC_SSP0->DR = 0xFF;    // dummy write to generate clock
while ( (LPC_SSP0->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE );
return LPC_SSP0->DR;

I have checked the SPI clock and the MISO pin with a sope - there are the correct signals, but DR is always empty.

Has anyone an idea?

Thanks
Thomas
0 Kudos

646 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Jul 08 17:12:28 MST 2011
Obviously we are not talking about

...\LPCXpresso_4.0.5_123\lpcxpresso\Examples\NXP\LPC1000\LPC17xx\NXP_LPCXpresso1769_MCB1700_2011-02-11.zip

SSP sample for EEPROM access?
0 Kudos