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

Just an example about using SPI

Dear All,

I'm working on SPI communication on two LPC2138. I prepared a board based on MCB2130 and just want that first LPC2138 works as Master and second works as Slave. I want to make them communicate as bi-directional and via interrupt. Could you please give me an example works on Realview Compiler? I couldn't make work the example spi file in lpc21xx_insidersguide.zip
I also couldn't make work which is listed in philips LPC2138 pages.

Opti

Parents
  • Hellow,

    I took your advice and started to debug example code. I realized that spi startup code is a little problem. Here is my code and schematic :

    #include <LPC21xx.H>                            /* LPC21xx definitions */
    #include <string.h>                            /* LPC21xx definitions */
    #define SPI_OK 0
    #define SPI_ERROR 1
    #define SPI_BUSY 2
    
    
    static unsigned char   state;      // State of SPI driver
    //static unsigned char   msg[5];       // pointer to SPI data buffer
    static unsigned char   msg[5];       // pointer to SPI data buffer
    static unsigned char   count;      // nr of bytes send/received
    long timeval;
    
    void wait (void)  {                             /* wait function */
      unsigned long i;
    
      i = timeval;
      while ((i + 10) != timeval);                  /* wait 100ms */
    }
    
    /* Timer Counter 0 Interrupt executes each 10ms @ 60 MHz CPU Clock */
    void tc0 (void) __irq  {
      ++timeval;
      T0IR        = 1;                            // Clear interrupt flag
      VICVectAddr = 0;                            // Acknowledge Interrupt
    }
    
    /* Setup the Timer Counter 0 Interrupt */
    void init_timer (void) {
      T0MR0 = 149999;                             // 10mSec = 150.000-1 counts
      T0MCR = 3;                                  // Interrupt and Reset on MR0
      T0TCR = 1;                                  // Timer0 Enable
      VICVectAddr0 = (unsigned long)tc0;          // set interrupt vector in 0
      VICVectCntl0 = 0x20 | 4;                    // use it for Timer 0 Interrupt
      VICIntEnable = 0x00000010;                  // Enable Timer0 Interrupt
    }
    
    void vSPI0_ISR(void) __irq
    {
        if ((S0SPSR & 0xF8) == 0x80)
        {
            ++count;
                    if (count < 40)
                S0SPDR = msg[count-1];         // sent next byte
            else
                state = SPI_OK;        // transfer completed
        }
        else                           // SPI error
        {
            *msg = S0SPDR;             // dummy read to clear flags
            state = SPI_ERROR;
        }
        S0SPINT = 0x01;                // reset interrupt flag
        VICVectAddr = 0;               // reset VIC
    }
    
    static void SPI_Init(void)
    {
    
            VICVectAddr2 = ( unsigned long ) vSPI0_ISR;
            VICVectCntl2 = 0x02A;
            VICIntEnable |= 0x0400;
    
            PINSEL0=0x5500;   // Configure Pin Connect Block
            VPBDIV=0x01;      // Set pclk to same as cclk
            S0SPCCR=0x08;     // Set to highest speed for SPI at 60 MHz -> 7.5 MHz
            VICIntSelect &= ~( 0x0400 );
            S0SPINT=0x01;     // Device selected as master
            S0SPCR=0xA0;
    }
    
    int main (void)  {
      unsigned int j;                               /* LED var */
      unsigned long volatile start;  // volatile avoids loop optimization
    
    /*
      for (start = 0; start < 10000000; start++) {
        ;    // wait for debugger connection (about 0.3 sec)
      }
    */
    
            SPI_Init();
    
            IODIR1 = 0xFF0000;                            /* P1.16..23 defined as Outputs */
            init_timer();
    
            S0SPDR=0x42;
            strcpy(msg, "OPTIZ");
    
            count = 0;
    
            while (1)  {
        for (j = 0x010000; j < 0x800000; j <<= 1) { /* Blink LED 0,1,2,3,4,5,6 */
          IOSET1 = j;                               /* Turn on LED */
          wait ();                                  /* call wait function */
          IOCLR1 = j;                               /* Turn off LED */
        }
        for (j = 0x800000; j > 0x010000; j >>=1 ) { /* Blink LED 7,6,5,4,3,2,1 */
          IOSET1 = j;                               /* Turn on LED */
          wait ();                                  /* call wait function */
          IOCLR1 = j;                               /* Turn off LED */
        }
      }
    }
    

    img155.imageshack.us/.../spi.jpg
    img195.imageshack.us/.../osc.jpg

    I couldnt fix "count" variable. If i decrease count value, it stops.. What do you say about this?

    Optizyme

Reply
  • Hellow,

    I took your advice and started to debug example code. I realized that spi startup code is a little problem. Here is my code and schematic :

    #include <LPC21xx.H>                            /* LPC21xx definitions */
    #include <string.h>                            /* LPC21xx definitions */
    #define SPI_OK 0
    #define SPI_ERROR 1
    #define SPI_BUSY 2
    
    
    static unsigned char   state;      // State of SPI driver
    //static unsigned char   msg[5];       // pointer to SPI data buffer
    static unsigned char   msg[5];       // pointer to SPI data buffer
    static unsigned char   count;      // nr of bytes send/received
    long timeval;
    
    void wait (void)  {                             /* wait function */
      unsigned long i;
    
      i = timeval;
      while ((i + 10) != timeval);                  /* wait 100ms */
    }
    
    /* Timer Counter 0 Interrupt executes each 10ms @ 60 MHz CPU Clock */
    void tc0 (void) __irq  {
      ++timeval;
      T0IR        = 1;                            // Clear interrupt flag
      VICVectAddr = 0;                            // Acknowledge Interrupt
    }
    
    /* Setup the Timer Counter 0 Interrupt */
    void init_timer (void) {
      T0MR0 = 149999;                             // 10mSec = 150.000-1 counts
      T0MCR = 3;                                  // Interrupt and Reset on MR0
      T0TCR = 1;                                  // Timer0 Enable
      VICVectAddr0 = (unsigned long)tc0;          // set interrupt vector in 0
      VICVectCntl0 = 0x20 | 4;                    // use it for Timer 0 Interrupt
      VICIntEnable = 0x00000010;                  // Enable Timer0 Interrupt
    }
    
    void vSPI0_ISR(void) __irq
    {
        if ((S0SPSR & 0xF8) == 0x80)
        {
            ++count;
                    if (count < 40)
                S0SPDR = msg[count-1];         // sent next byte
            else
                state = SPI_OK;        // transfer completed
        }
        else                           // SPI error
        {
            *msg = S0SPDR;             // dummy read to clear flags
            state = SPI_ERROR;
        }
        S0SPINT = 0x01;                // reset interrupt flag
        VICVectAddr = 0;               // reset VIC
    }
    
    static void SPI_Init(void)
    {
    
            VICVectAddr2 = ( unsigned long ) vSPI0_ISR;
            VICVectCntl2 = 0x02A;
            VICIntEnable |= 0x0400;
    
            PINSEL0=0x5500;   // Configure Pin Connect Block
            VPBDIV=0x01;      // Set pclk to same as cclk
            S0SPCCR=0x08;     // Set to highest speed for SPI at 60 MHz -> 7.5 MHz
            VICIntSelect &= ~( 0x0400 );
            S0SPINT=0x01;     // Device selected as master
            S0SPCR=0xA0;
    }
    
    int main (void)  {
      unsigned int j;                               /* LED var */
      unsigned long volatile start;  // volatile avoids loop optimization
    
    /*
      for (start = 0; start < 10000000; start++) {
        ;    // wait for debugger connection (about 0.3 sec)
      }
    */
    
            SPI_Init();
    
            IODIR1 = 0xFF0000;                            /* P1.16..23 defined as Outputs */
            init_timer();
    
            S0SPDR=0x42;
            strcpy(msg, "OPTIZ");
    
            count = 0;
    
            while (1)  {
        for (j = 0x010000; j < 0x800000; j <<= 1) { /* Blink LED 0,1,2,3,4,5,6 */
          IOSET1 = j;                               /* Turn on LED */
          wait ();                                  /* call wait function */
          IOCLR1 = j;                               /* Turn off LED */
        }
        for (j = 0x800000; j > 0x010000; j >>=1 ) { /* Blink LED 7,6,5,4,3,2,1 */
          IOSET1 = j;                               /* Turn on LED */
          wait ();                                  /* call wait function */
          IOCLR1 = j;                               /* Turn off LED */
        }
      }
    }
    

    img155.imageshack.us/.../spi.jpg
    img195.imageshack.us/.../osc.jpg

    I couldnt fix "count" variable. If i decrease count value, it stops.. What do you say about this?

    Optizyme

Children
  • The layout of your code seems to have lost something in posting. Note that you need to use spaces not TABs for indentation - the interpretation of TAB characters is (almost) entirely unpredictable!

    Your image links don't seem to work.

    Please describe in more detail what seems to be the problem with the 'count' variable?