LPC11C24 SPI Program

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

LPC11C24 SPI Program

1,727 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rohit on Sun Jun 07 22:45:16 MST 2015
Hi

I have been trying to commincate between my lpc11c24(master) and altera  fpga(slave) via spi protocol.
i created my own program for the same which is given below.

#include "chip.h"
#include "board.h"
#include "LPC11xx.h"

typedef struct
{
uint8_t *txBuff;         /**< Pointer to array of bytes to be transmitted */
int     txSz;// Number of bytes in transmit array,
 

uint8_t *rxBuff;        /**< Pointer memory where bytes received from I2C be stored */

int     rxSz;// Number of bytes to received,

} SSP_XFER;



static uint8_t MOSI[16];
static uint8_t MISO[16];


void read_init()
{

    LPC_IOCON->PIO1_6                               |= 0x01;                                           //configure UART RXD pin
    LPC_IOCON->PIO1_7                               |= 0x01;                                           //configure UART TXD pin
    LPC_SYSCON->SYSAHBCLKCTRL          |= (1<<12);                                      //enable clock to UART
    LPC_UART->FCR                                      |= 0x01;                                           //enable FIFO
    LPC_UART->LCR                                      |= 0x03;                                           //set for 8 bit data width, 1 stop bit, no parity
    LPC_UART->TER                                      |= 0x80;                                           //enable transmission
    Chip_UART_SetBaud(LPC_USART, 115200);
}


static int con_get_input(const char *str)
{
int val=0,j;
uint8_t i;
ADDRESS:
DEBUGOUT("%s", str);

while(!(LPC_UART->LSR & 0x01));
i=LPC_UART->RBR;

if(i>=48 && i<=57)
{
while(i != 0)
{
val=val+(i-48);
val=val*10;
for(j=0;j<0xFFFF;j++);
i=LPC_UART->RBR;

}

DEBUGOUT("%d",val/10);
return (val/10);
}
else
{
DEBUGOUT("\r\nError..!!! Please enter a number\r\n");
goto ADDRESS;

}
}


void ssp_init()
{
DEBUGOUT("\r\nInitializing SPI.....!!!\r\n");

      LPC_SYSCON->SYSAHBCLKCTRL                |= (1<<11);       // enable clock to ssp0
           LPC_SYSCON->SSP0CLKDIV                       = 0x9B;
      LPC_SYSCON->PRESETCTRL                       = 0x01;

      LPC_IOCON->PIO0_8   |= 0x01;        //MISO Config
      LPC_IOCON->PIO0_9           |= 0x01;        //MOSI Config
      LPC_IOCON->PIO0_2   |= 0x01; //SSEL0 config
      LPC_IOCON->SCK_LOC  |= 0x02; //set sck0 in PIO0_6
      LPC_IOCON->PIO0_6   |= 0x02; //set PIO0_6 as SCK

      LPC_SSP0->CPSR    = 0x0F; 
      LPC_SSP0->CR0    = 0x0F; 
      LPC_SSP0->CR1    = 0x02;   // SSP master mode

}



static void ssp_rw_input(SSP_XFER *xfer,int ops)
{
uint8_t addr,data;

if(ops==1)
{
addr=con_get_input("\r\nEnter address to which data should be written:");
MOSI[0]=addr;
xfer->txBuff=MOSI;

data=con_get_input("\r\nEnter the data to be written:");                                         //writing only 1 byte of data for now
MOSI[1]=data;
xfer->txBuff =MOSI;
xfer->txSz=1;
}
else

if(ops==2)
{
addr=con_get_input("\r\nEnter address to from which data is to be read from:");
MOSI[0]=addr;
xfer->txSz = 1;
xfer->txBuff = MOSI;
}
}

int main(void)
{
char ch[]="\r\n\t0)exit demo"
   "\r\n\t1)write data"
"\r\n\t2)read data";
int len=2;
int flag=0;
static SSP_XFER xfer;

SystemCoreClockUpdate();
Board_Init();
read_init();

DEBUGOUT("\r\nWelcome to SPI Protocol");

int option;
ssp_init();
LABEL:

while(!flag)
{
DEBUGOUT("%s",ch);
     option=con_get_input("\r\nSelect option:");

     switch(option)
     {
      case 0:flag=1;
          DEBUGOUT("\r\n Exiting SPI demo....goodbye...\r\n");
        break;

      case 1: ssp_rw_input(&xfer,1);
           while(!(LPC_SSP0->SR & 0x02)); //check whether transmit buffer is full
           while(len)
           {
           LPC_SSP0->DR = *xfer.txBuff++;
           len--;
           }
           while(!(LPC_SSP0->SR & 0x01));// wait until byte is sent

           DEBUGOUT("\r\nData sent.... :-)");
           goto LABEL;

      case 2:
           ssp_rw_input(&xfer,2);
           while(!(LPC_SSP0->SR & 0x02));//check whether transmit buffer is full
           LPC_SSP0->DR = *xfer.txBuff;

           while(!(LPC_SSP0->SR & 0x01));// wait until byte is sent

           while(!(LPC_SSP0->SR & 0x04));//check whether recieve buffer is full
           MISO[0] = LPC_SSP0->DR;

                      DEBUGOUT("\r\nRecieved Data-->");
                      DEBUGOUT("%d",MISO[0]);
          goto LABEL;
      }
    }
return 0 ;
}

the program returns no error and wrting data has been successfull.however reading the data is not working.it always returns zero.

Can someone please help me ,i am new to LPC11C24 . Is my program entirely wrong?
PS: i did have a look at the example program,however couldnt understand much so i made this program by refering the datasheet .
0 Kudos
Reply
7 Replies

1,391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by 1234567890 on Sun Jun 21 03:29:13 MST 2015
- As I mentioned before: Check your SPI clock settings in ssp_init()!
- What is your intended speed?
- And in LPC_SSP0->CPSR = 0x0F;: Is this an even value? See table 213 in the UM.
- uint8_t *txBuff; and static uint8_t MOSI[16];, but in LPC_SSP0->CR0 = 0x0F; you code a 16 bit transfer
- LPC_SSP0->CR1 = 0x02; // SSP master mode => Coding doesn't match with comment
- Programming with labels and 'goto'...
- In ssp_rw_input(): xfer->txBuff = MOSI ==> two times. And MOSI[1] = data. data is always zero.

You should really use LPCOpen and start from scratch. Adapt an example from LPCOpen.
0 Kudos
Reply

1,391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rohit on Sun Jun 14 22:08:17 MST 2015

#include "chip.h"
#include "board.h"
#include "LPC11xx.h"
#define LPC_SSP           LPC_SSP0


typedef struct {
 uint8_t *txBuff;/**< Pointer to array of bytes to be transmitted */
int     txSz;/**< Number of bytes in transmit array,
   if 0 only receive transfer will be carried on */
uint8_t *rxBuff;/**< Pointer memory where bytes received from I2C be stored */
int     rxSz;/**< Number of bytes to received,
   if 0 only transmission we be carried on */
} SSP_XFER;



static uint8_t MOSI[16];
static uint8_t MISO[16];
void read_init()
{

    LPC_IOCON->PIO1_6                            |= 0x01;      //configure UART RXD pin
    LPC_IOCON->PIO1_7                            |= 0x01;      //configure UART TXD pin
    LPC_SYSCON->SYSAHBCLKCTRL       |= (1<<12);   //enable clock to UART
    LPC_UART->FCR                                   |= 0x01;      //enable FIFO
    LPC_UART->LCR                                   |= 0x03;      //set for 8 bit data width, 1 stop bit, no parity
    LPC_UART->TER                                   |= 0x80;      //enable transmission
    Chip_UART_SetBaud(LPC_USART, 115200);
}


static int con_get_input(const char *str)
{
int val=0,j;
uint8_t i;
ADDRESS:
DEBUGOUT("%s", str);
while(!(LPC_UART->LSR & 0x01));
i=LPC_UART->RBR;
if(i>=48 && i<=57)
{
while(i != 0)
{
val=val+(i-48);
val=val*10;
for(j=0;j<0xFFFF;j++);
i=LPC_UART->RBR;

}

DEBUGOUT("%d",val/10);
return (val/10);
}
else
{
DEBUGOUT("\r\nError..!!! Please enter a number\r\n");
goto ADDRESS;

}
}


void ssp_init()
{
DEBUGOUT("\r\nInitializing SPI.....!!!\r\n");
  LPC_SYSCON->SYSAHBCLKCTRL  |= (1<<11);       // enable clock to ssp0
       LPC_SYSCON->SSP0CLKDIV  = 0x9B;
  LPC_SYSCON->PRESETCTRL      = 0x01;
      LPC_IOCON->PIO0_8   |= 0x01;     //MISO Config
      LPC_IOCON->PIO0_9           |= 0x01;     //MOSI Config
      LPC_IOCON->PIO0_2   |= 0x01; //SSEL0 config
      LPC_IOCON->SCK_LOC  |= 0x02; //set sck0 in PIO0_6
      LPC_IOCON->PIO0_6   |= 0x02; //set PIO0_6 as SCK
      LPC_SSP0->CPSR    = 0x0F;
      LPC_SSP0->CR0    = 0x0F;
      LPC_SSP0->CR1    = 0x02;   // SSP master mode

}
static void ssp_rw_input(SSP_XFER *xfer,int ops)
{
uint8_t addr,data;
if(ops==1)
{
addr=con_get_input("\r\nEnter address to which data should be written:");
MOSI[0]=addr;
xfer->txBuff=MOSI;
data=con_get_input("\r\nEnter the data to be written:");  //writing only 1 byte of data for now
MOSI[1]=data;
xfer->txBuff =MOSI;
xfer->txSz=2;
}
else
if(ops==2)
{
addr=con_get_input("\r\nEnter address to from which data is to be read from:");
MOSI[0]=addr;
xfer->txSz = 1;
xfer->txBuff = MOSI;
}
}

int main(void)
{
char ch[]="\r\n\t0)exit demo"
   "\r\n\t1)write data "
   "\r\n\t2)read data";

int len=1;
int flag=0;
static SSP_XFER xfer;
SystemCoreClockUpdate();
Board_Init();
read_init();



DEBUGOUT("\r\nWelcome to SPI Protocol");
int option;
ssp_init();
LABEL:
while(!flag)
{
DEBUGOUT("%s",ch);
     option=con_get_input("\r\nSelect option:");
     switch(option)
     {
      case 0:flag=1;
          DEBUGOUT("\r\n Exiting SPI demo....goodbye...\r\n");
        break;

      case 1: ssp_rw_input(&xfer,1);
           while(!(LPC_SSP0->SR & 0x02)); //check whether transmit buffer is full
           while(len)
           {
           LPC_SSP0->DR = xfer.txBuff;
           xfer.txBuff++;
           len--;
           }
           while(!(LPC_SSP0->SR & 0x01));// wait until byte is sent
           DEBUGOUT("\r\nData sent.... :-)");
           goto LABEL;

      case 2:
           ssp_rw_input(&xfer,2);
           while(!(LPC_SSP0->SR & 0x02));//check whether transmit buffer is full
           LPC_SSP0->DR = 0x0100;
           while(!(LPC_SSP0->SR & 0x01));// wait until byte is sent

           //while(!(LPC_SSP0->SR & 0x04));//check whether receive buffer is full
           MISO[0] = LPC_SSP0->DR;
        DEBUGOUT("\r\nRecieved Data-->");
        DEBUGOUT("%d",MISO[0]);
          goto LABEL;
      }
    }
return 0 ;
}


This is the actual code. I use lpcxpresso ide and lpc11c24 development board if thats what you meant by wheather i use custom board or not.
0 Kudos
Reply

1,391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by 1234567890 on Sat Jun 13 05:04:30 MST 2015
Do you use a LPCXpresso or a custom board?

Quote:
By the way is the spi data transfer part of the code correct?


You wrote that you have updated the code. Please post the actual code.
0 Kudos
Reply

1,391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rohit on Thu Jun 11 21:50:52 MST 2015
On the hardware side i am using lpc11c24 as master, altera arria dev board as slave, also i am using usb to rs232 convertor to transfer serial data from pc to the master.Thats why i am using uart.

I am using lpcxpresso ide and Hterm serial monitor to input the serial data and to view the output values.

In the above program i what i planned to do was to first send a reg address to the slave and then the data, via spi there after to read the data from that particular reg address via MISO . The values inputted by the user is serially transfered to the master from the pc and the data obtained by the slave is printed on the serial monitor.

The writting part works i believe as when i check the waveform using oscilloscope ,it shows succesful writting but data is not being read from the slave properly. I always 0 as the read data even the MISO waveform line shows random values.

By the way is the spi data transfer part of the code correct?

Thanks in advance
0 Kudos
Reply

1,391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by 1234567890 on Thu Jun 11 09:06:39 MST 2015
You should reduce your code to the absolute minimum. Just enough to send data to a register and read it back. No UART, printf and so on. Use the debugger to read the values.
By the way: What hard- and software do you use?
0 Kudos
Reply

1,391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rohit on Wed Jun 10 00:31:13 MST 2015
I understand your concern sir i have tried and edited the code to make it more readable.

i have corrected the errors you pointed out and its still not working properly.

I did go through the example ssp program and did make this code based on it.but the reading of data from the slave still is giving erroreneus results.

0 Kudos
Reply

1,391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by 1234567890 on Mon Jun 08 11:48:02 MST 2015
First of all: Please format the code! This way it's nearly unreadable.
Then you should use LPCOpen. If you want to see 'raw' values (and no delivered functions) use appropriate preprocessor options.

I haven't read all the code, but lines like
LPC_SYSCON->SSP0CLKDIV |= 0x9B;
are probably not what you wanted. And it's potentially dangerous in this case as well because one should write an absolute value to this register!
LPC_SSP0->CPSR = 0x0F; // SSP max speed

doesn't match with the comment. On the first glance both lines result in a realy slow SPI clock.

Edit: And check this line as well:
LPC_SSP0->CR0 = 0x0F; // SSP max speed, 8 bits


You should really step through a LPCOpen example to understand it. Hovering code with mouse pointer shows details; right click open declaration and so on.
0 Kudos
Reply