This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LPC2148 SPI Problem

Hi

I have been working on LPC2148 for a project.
I have tried to get the spi0 working.

Currently the code compiles without a problem but is not responding as it is supposed to.
I would like to know if there is any problem with the code in terms of SPI.

#include <lpc214x.h> //Includes LPC2148 register definitions

void spi_init();
void spi_send(char p);
char spi_receive();

int main(void)
{ char p; int i=0; PINSEL0 = (1<<8)|(1<<10)|(1<<12)|(1<<14); // Enable UART1 Rx and Tx pins PINSEL1 = 0x00000000; PINSEL2 = 0x00000000; IO0DIR = (1<<14); IO0CLR |=(1<<14); IO1DIR = (1<<19) | (1<<18) | (1<<17) | (1<<16); spi_init();

while (1) { spi_send('0'); while(p!='0') { p=spi_receive(); }

spi_send('x'); while(p!='x') { p=spi_receive(); }

spi_send('f'); while(p!='f') { p=spi_receive(); }

spi_send('f'); while(p!='f') { p=spi_receive(); } i+=1; p='o'; switch(i%4) { case 1: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<19); break; case 2: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<18); break; case 3: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<17); break; case 0: IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16); IO1SET=(1<<16); break;

}
} }
void spi_init()
{ S0SPCR|=(1<<5); S0SPCCR=0x60;

}
void spi_send(char p)
{ int value; value=(int)p; S0SPDR = value; while (!(S0SPSR & 0x80));
} char spi_receive()
{ char p; while (!(S0SPSR & 0x80)); p=(char)S0SPDR; return p;
}

Thanks for the help!!

  • Doesn't look readable.

    You forgot to tag it as code.

    You forgot to use comments, to actually document your code. Magic constants doesn't help you.

  • I apologize for the inconvenience...here is the code with comments:

    The code sends a predefined data and on getting the same data back ,changes the state of its pins .LPC2148 acts as a master to a device which relays the same data sent to it.

    
    #include  <lpc214x.h>              //Includes LPC2148 register definitions
    
    
    void spi_init();                        //To define SPI
    void spi_send(char p);
    char spi_receive();
    
    int  main(void)
    {
            char p;
            int i=0;
       PINSEL0 = (1<<8)|(1<<10)|(1<<12)|(1<<14);                // Enable MISO MOSI SCK and Slave Select
       PINSEL1 = 0x00000000;
       PINSEL2 = 0x00000000;
             IO0DIR = (1<<14);
             IO0CLR |=(1<<14);                                        //Keep slave select as negetive always
       IO1DIR = (1<<19) | (1<<18) | (1<<17) | (1<<16);
                    spi_init();                                     //Initialize spi
    
            while (1)
            {
                    spi_send('0');                                  //Send a character and receive the same character
                    while(p!='0')
                    {
                            p=spi_receive();
                    }
    
                    spi_send('x');
                    while(p!='x')
                    {
                            p=spi_receive();
                    }
    
                    spi_send('f');
                    while(p!='f')
                    {
                            p=spi_receive();
                    }
    
                    spi_send('f');
                    while(p!='f')
                    {
                            p=spi_receive();
                    }
                    i+=1;
                    p='o';
                    switch(i%4)     //change state of pin when the given configuration is sent
                    {
                            case 1:
                            IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16);
                            IO1SET=(1<<19);
                            break;
                            case 2:
                            IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16);
                            IO1SET=(1<<18);
                            break;
                            case 3:
                            IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16);
                            IO1SET=(1<<17);
                            break;
                            case 0:
                            IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16);
                            IO1SET=(1<<16);
                            break;
    
    }
    }
    }
    void spi_init()
    {
            S0SPCR|=(1<<5);          //Master mode
            S0SPCCR=0x60;            //12500 Hz clock
    
    }
    void spi_send(char p)
    {
            int value;
            value=(int)p;
            S0SPDR = value;
      while (!(S0SPSR & 0x80));         //checks for data flag to go off
    }
    char spi_receive()
    {
            char p;
      while (!(S0SPSR & 0x80));          //waits till data is received.
            p=(char)S0SPDR;
            return p;
    }
    
    

  • ----------------------------------
    STARTUP CODE (startup_LPC17xx.s)
    ----------------------------------
    Reset_Handler PROC
    EXPORT Reset_Handler [WEAK]
    IMPORT SystemInit
    IMPORT __main
    MOV R0,#0
    MSR CONTROL, R0
    LDR R0, =SystemInit
    BLX R0
    LDR R0, =__main
    BX R0
    ENDP

    ----------------------------
    EXECUTE USER CODE FUNCTION
    ----------------------------
    void execUserCode( void )
    { __disable_irq( );
    SCB -> VTOR = ( USER_FLASH_START & 0x1FFFFF80 );
    bootJump( USER_FLASH_START ); // User Flash start is the position of the vector table for the app }

    -----------------------------------
    BOOT JUMP TO APPLICATION FUNCTION
    -----------------------------------
    __asm void bootJump( U32 address )
    { LDR SP, [R0]
    LDR PC, [R0, #4]
    }

  • Thank you for your answer

    I use flash magic to program the MCU and load the value of the flash start and all...

    I haven't used any of the above code for UART and it works.So I feel that is not the solution.
    Is there something else wrong with the code?or am i forgetting to initialize something important?

  • I have tried to loop back MOSI and MISO and test.

    The code appears to be working sometimes based on the led signals...
    This is what I could infer:

    1)code is sending a character
    2)Code is receiving a character
    3)The received character is not 0xff or the looped back character but something else.

    Is there a specific clock i need to use for spi?I use 12Mhz and use 1/8 th for spi.
    Should I initialize anything for loopback or receive?

    The datasheet says read the S0SPSR to clear register before receiving data...how do I do that?

    Here is the code for your reference

    
    #include  <lpc214x.h>              //Includes LPC2148 register definitions
    
    
    void spi_init();                        //To define SPI
    void spi_send(char p);
    char spi_receive();
    
    int  main(void)
    {
    
            char p='l';
            int i=0,j=0,k=0;
            for(j=0;j<12000;j++)
                            {
                                            for(k=0;k<1000;k++);
                            }
       PINSEL0 = (1<<8)|(1<<10)|(1<<12)|(1<<14);                // Enable MISO MOSI SCK and Slave Select
       PINSEL1 = 0x00000000;
       PINSEL2 = 0x00000000;
             IO0DIR = (1<<14);
             IO0SET |=(1<<14);                                        //Keep slave select as negetive always
       IO1DIR = (1<<19) | (1<<18) | (1<<17) | (1<<16);
                    spi_init();                                     //Initialize spi
    
            while (1)
            {
    
                    spi_send('0');
    
            //Send a character and receive the same character
                    while(p!='0')
                    {
    
                            p=spi_receive();
                            if(p==(char)0xff)
                            {
                                    IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16);                 //to check if no data is received without interrupt flag
                            }
                    }
                    while(p=='0')
                    {
                            IO1CLR=(1<<19)|(1<<18)|(1<<17)|(1<<16);                         //if data is received properly
                            IO1SET=(1<<19)|(1<<17)|(1<<16);
                            while(1);
                    }
    
    
    }
    }
    
    void spi_init()
    {
            S0SPCR|=0x20;         //Master Mode
            S0SPCCR=0x8;
    
    }
    void spi_send(char p)
    {
            IO0CLR |=(1<<14);
            S0SPDR = p;
      while ((!S0SPSR & 0x80));
            S0SPSR &=~ 0x80;
            IO0SET |=(1<<14);
    }
    char spi_receive()
    {
            char p;
            IO0CLR |=(1<<14);
            S0SPDR=0xff;
            IO1SET=(1<<18)|(1<<17)|(1<<16);     //to check if function is entered
      while ((!S0SPSR & 0x80));
            p=S0SPDR;
            IO1SET=(1<<19)|(1<<17)|(1<<16);     //to check if data is received
            return p;
            IO0SET |=(1<<14);
    }
    

    Any help is gratefully appreciated.

    Thank You