EmbeddedRelated.com
Forums

SPI is not working on LPC 2294 board

Started by phan...@gmail.com March 4, 2013
Hi All,
the SPI code is working fine with keil simulator it is going to ISR whenever SPIF is set.
but when the same code is loaded to LPC 2294 hardware board it is not working
and indefinitely waiting for SPIF bit.
In the above case, whenever data is written to S0SPDR interrupt is getting generated (observed on Vector Interrupt Controller) but it is not entering in to ISR and waiting continuously for SPIF.

no activity is detected on the SPI port pins(on logic analyzer )

other interrupts are working fine(timer is checked) but I am understanding why SPI is not working

the code is for interfacing the SPI flash(S70fl256)with LPC2294 and the code is as follows

#define NULL ((void *)0)
#define False (0)

#define True (1)

/* SPI */

#define SPI0_ABORT 0x08
#define SPI0_MODE_FAULT 0x10
#define SPI0_OVERRUN 0x20
#define SPI0_COL 0x40
#define SPIF 1 << 7
#define INTERRUPT_MODE 1

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned int Bool;
#include
#include "spi.h" //all prototypes and variables def
/*******************************************************************
* Name: Wait
* Desc: Delay Function
* Inputs: count
* outputs: None
* Remarks if any:
*******************************************************************/
void Wait(unsigned long cnt)
{
while(--cnt);

}

/*******************************************************************
* Name : Flash_MemWrite
* Desc: Flash Momory write function
* Inputs: Memory Address offset and value
* outputs: None
*
*******************************************************************/
void Flash_MemWrite(unsigned char *buf,unsigned char *SPI0Add,unsigned char Length)
{
unsigned char i,Dummy;
IOCLR1= 0x00010000; /* to generate #CS1 of SPI flash*/
Wait(5);
S0SPDR = 0x06; /* to set write enable latch */
while ( !(S0SPSR & SPIF) );
Dummy = S0SPDR; /* Flush the RxFIFO */
IOSET1= 0x00050000; /* to disable #CS1 and to pull up #Hold of SPI flash */

IOCLR1= 0x00010000; /* to generate #CS1 of SPI flash*/
Wait(5);
S0SPDR = 0x02; /*Page Program (PP) command enables memory array data to be programmed*/
while ( !(S0SPSR & SPIF) );
Dummy = S0SPDR; /* Flush the RxFIFO */
/* before sending data 3 bytes of address has to be sent*/

for ( i = 0; i < 3; i++ )
{
S0SPDR = *SPI0Add;
while ( !(S0SPSR & SPIF) );

Dummy = S0SPDR; /* Flush the RxFIFO */
SPI0Add++;
}
/* now send the data */

if ( Length == 0 )
{ return; }
for ( i = 0; i < Length; i++ )
{
S0SPDR = *buf;
while ( !(S0SPSR & SPIF) );

Dummy = S0SPDR; /* Flush the RxFIFO */
buf++;
}
Wait(0xF);

IOSET1= 0x00050000; /* to disable #CS1 and to pull up #Hold of SPI flash */

}
/*******************************************************************
* Name : Flash_MemRead
* Desc: Flash Memory Read
* Inputs: Memory Address
* outputs: pointer to Addressed Memory location
*
*******************************************************************/
unsigned char *Flash_MemRead(unsigned char *SPI0Add, unsigned char Length)
{
unsigned char temp[256],Dummy,i;
IOCLR1= 0x00010000; /* to generate #CS1 of SPI flash*/
Wait(5);
S0SPDR = 0x03; /* read command */
while ( !(S0SPSR & SPIF) );
Dummy = S0SPDR; /* Flush the RxFIFO */
/* before reading data 3 bytes of address has to be sent*/

for (i = 0; i < 3; i++ )
{
S0SPDR = *SPI0Add;
while ( !(S0SPSR & SPIF) );

Dummy = S0SPDR; /* Flush the RxFIFO */
SPI0Add++;
}
/* now receive the data */

for ( i = 0; i < Length; i++ )
{
S0SPDR = 0xFF;
while ( !(S0SPSR & SPIF) );
temp[i]=S0SPDR;
}
IOSET1= 0x00050000; /* to disable #CS1 and to pull up #Hold of SPI flash */
return temp;

}
/*******************************************************************
* Name : DefinePins
* Desc: For configuring port pins and setting the direction
* Inputs: None
* outputs: None
*
*******************************************************************/
void DefinePins(void)
{

PINSEL0 = 0x2000155C;
PINSEL1 = 0x000002A8;
IOSET1 = 0x00050000; // to disable #CS1 and to pull up #Hold /*of SPI flash */
IODIR1 = 0x00050000;
}

/*****************************************************************************
** Function name: SPI0Handler
**
** Descriptions: SPI0 interrupt handler- connected to SPI Flash
**
** parameters: None
** Returned value: None
**
**************************************************************************/

void SPI0Handler (void) __irq
{
S0SPINT = 0X01; /* clear interrupt flag */
VICVectAddr = 0; /* Acknowledge Interrupt */

}
/*******************************************************************
* Name :default_isr
* Desc: default ISR for all non vectored interrupts
* Inputs: None
* outputs: None
*
*******************************************************************/

void default_isr(void)
{
;
}

/*******************************************************************
* Name :Spi_Init
* Desc: To initialise the SPI1 and SPI0 ports as Master and the SPI data rate as PCLK/10 => 60/10=6 Mbps
* Inputs: None
* outputs: None
*
*******************************************************************/
void Spi_Init()
{
PCONP=0X0D86; /* to enable I2C and SPI ports */
S0SPCR = 0x00A8; //SPI0-active high, master,int enabled, 8 //bit format and ckocl phase is 1
// P0.4 SCK0, P0.5 MISO0, P0.6 MOSI0
S0SPCCR = 0x0A;

#if INTERRUPT_MODE

//SPI0 priority is 3
VICIntEnClr =0xFFFFFFFF; /* Disable Interrupts */
VICVectAddr3 = (unsigned long)SPI0Handler; /* set interrupt vector */
VICVectCntl3 = 0x00000020 | 10;
VICIntEnable |= 0x00000400; // 10 th bit to enable SPI0
S0SPCR = 0x00A8; //8 bits per transfer,interrupt enable, master //for SPI flash

#endif
return;
}
/*******************************************************************
* Name: Flash_Test
* Desc: to test the spi flash
* Inputs: None
* outputs: None
* Remarks if any:
*******************************************************************/
Bool Flash_Test(void)
{
Bool Mem_flag= True;
unsigned char *temp,SPI0Data[256],SPI0Add[3];
unsigned char i;
SPI0Add[0]=0x1;//10;
SPI0Add[1]=0x2;//0;
SPI0Add[2]=0x3;//0;
for (i=0 ;i < 2; i++) // 256
{
SPI0Data[i] =0x0AA;
}
Flash_MemWrite(SPI0Data,SPI0Add,2); //256
temp = Flash_MemRead(SPI0Add,2); //256

for (i=0 ;i < 2; i++) //256
{
if(temp[i]!= 0x0AA)
{
Mem_flag = False;
break;
}
}
if(Mem_flag)
{
return True;
}
else
{
return False;
}

}
/*******************************************************************
* Name : main
* Desc:
* Inputs: None.
* outputs: None.
*
*******************************************************************/
int main(void)
{
Bool flash_flag;
DefinePins(); /* Define Pinsel0,1;*/
Spi_Init();
VICDefVectAddr = (unsigned long)default_isr;
flash_flag=Flash_Test();

while(1);
}
please help me and let me know where I am missing.

Thank you in advance

An Engineer's Guide to the LPC2100 Series

Hi All,
>the SPI code is working fine with keil simulator it is going to ISR whenever SPIF is set.
>but when the same code is loaded to LPC 2294 hardware board it is not working
>and indefinitely waiting for SPIF bit.
>In the above case, whenever data is written to S0SPDR interrupt is getting generated (observed on Vector Interrupt Controller) but it is not entering in to ISR and waiting continuously for SPIF.
>
>no activity is detected on the SPI port pins(on logic analyzer )
>
>other interrupts are working fine(timer is checked) but I am understanding why SPI is not working
>
>the code is for interfacing the SPI flash(S70fl256)with LPC2294 and the code is as follows
>
>#define NULL ((void *)0)
>#define False (0)
>
>#define True (1)
>
>/* SPI */
>
>#define SPI0_ABORT 0x08
>#define SPI0_MODE_FAULT 0x10
>#define SPI0_OVERRUN 0x20
>#define SPI0_COL 0x40
>#define SPIF 1 < < 7
>#define INTERRUPT_MODE 1
>
>typedef unsigned char BYTE;
>typedef unsigned short WORD;
>typedef unsigned long DWORD;
>typedef unsigned int Bool;
>#include
>#include "spi.h" //all prototypes and variables def
>/*******************************************************************
>* Name: Wait
>* Desc: Delay Function
>* Inputs: count
>* outputs: None
>* Remarks if any:
>*******************************************************************/
>void Wait(unsigned long cnt)
>{
> while(--cnt);
>
>}
>
>/*******************************************************************
>* Name : Flash_MemWrite
>* Desc: Flash Momory write function
>* Inputs: Memory Address offset and value
>* outputs: None
>*
>*******************************************************************/
>void Flash_MemWrite(unsigned char *buf,unsigned char *SPI0Add,unsigned char Length)
>{
> unsigned char i,Dummy;
> IOCLR1= 0x00010000; /* to generate #CS1 of SPI flash*/
> Wait(5);
> S0SPDR = 0x06; /* to set write enable latch */
> while ( !(S0SPSR & SPIF) );
> Dummy = S0SPDR; /* Flush the RxFIFO */
> IOSET1= 0x00050000; /* to disable #CS1 and to pull up #Hold of SPI flash */
>
> IOCLR1= 0x00010000; /* to generate #CS1 of SPI flash*/
> Wait(5);
> S0SPDR = 0x02; /*Page Program (PP) command enables memory array data to be programmed*/
> while ( !(S0SPSR & SPIF) );
> Dummy = S0SPDR; /* Flush the RxFIFO */
>/* before sending data 3 bytes of address has to be sent*/
>
> for ( i = 0; i < 3; i++ )
> {
> S0SPDR = *SPI0Add;
> while ( !(S0SPSR & SPIF) );
>
> Dummy = S0SPDR; /* Flush the RxFIFO */
> SPI0Add++;
> }
>/* now send the data */
>
> if ( Length == 0 )
> { return; }
> for ( i = 0; i < Length; i++ )
> {
> S0SPDR = *buf;
> while ( !(S0SPSR & SPIF) );
>
> Dummy = S0SPDR; /* Flush the RxFIFO */
> buf++;
> }
> Wait(0xF);
>
> IOSET1= 0x00050000; /* to disable #CS1 and to pull up #Hold of SPI flash */
>
>}
>/*******************************************************************
>* Name : Flash_MemRead
>* Desc: Flash Memory Read
>* Inputs: Memory Address
>* outputs: pointer to Addressed Memory location
>*
>*******************************************************************/
>unsigned char *Flash_MemRead(unsigned char *SPI0Add, unsigned char Length)
>{
> unsigned char temp[256],Dummy,i;
> IOCLR1= 0x00010000; /* to generate #CS1 of SPI flash*/
> Wait(5);
> S0SPDR = 0x03; /* read command */
> while ( !(S0SPSR & SPIF) );
> Dummy = S0SPDR; /* Flush the RxFIFO */
> /* before reading data 3 bytes of address has to be sent*/
>
> for (i = 0; i < 3; i++ )
> {
> S0SPDR = *SPI0Add;
> while ( !(S0SPSR & SPIF) );
>
> Dummy = S0SPDR; /* Flush the RxFIFO */
> SPI0Add++;
> }
>/* now receive the data */
>
> for ( i = 0; i < Length; i++ )
> {
> S0SPDR = 0xFF;
> while ( !(S0SPSR & SPIF) );
> temp[i]=S0SPDR;
> }
> IOSET1= 0x00050000; /* to disable #CS1 and to pull up #Hold of SPI flash */
> return temp;
>
>}
>/*******************************************************************
>* Name : DefinePins
>* Desc: For configuring port pins and setting the direction
>* Inputs: None
>* outputs: None
>*
>*******************************************************************/
>void DefinePins(void)
>{
>
> PINSEL0 = 0x2000155C;
> PINSEL1 = 0x000002A8;
> IOSET1 = 0x00050000; // to disable #CS1 and to pull up #Hold /*of SPI flash */
> IODIR1 = 0x00050000;
> }
>
>/*****************************************************************************
>** Function name: SPI0Handler
>**
>** Descriptions: SPI0 interrupt handler- connected to SPI Flash
>**
>** parameters: None
>** Returned value: None
>**
>**************************************************************************/
>
>void SPI0Handler (void) __irq
>{
> S0SPINT = 0X01; /* clear interrupt flag */
> VICVectAddr = 0; /* Acknowledge Interrupt */
>
>}
>/*******************************************************************
>* Name :default_isr
>* Desc: default ISR for all non vectored interrupts
>* Inputs: None
>* outputs: None
>*
>*******************************************************************/
>
>void default_isr(void)
>{
>;
>}
>
>/*******************************************************************
>* Name :Spi_Init
>* Desc: To initialise the SPI1 and SPI0 ports as Master and the SPI data rate as PCLK/10 => 60/10=6 Mbps
>* Inputs: None
>* outputs: None
>*
>*******************************************************************/
>void Spi_Init()
>{
> PCONP=0X0D86; /* to enable I2C and SPI ports */
> S0SPCR = 0x00A8; //SPI0-active high, master,int enabled, 8 //bit format and ckocl phase is 1
> // P0.4 SCK0, P0.5 MISO0, P0.6 MOSI0
> S0SPCCR = 0x0A;
>
>#if INTERRUPT_MODE
>
> //SPI0 priority is 3
> VICIntEnClr =0xFFFFFFFF; /* Disable Interrupts */
> VICVectAddr3 = (unsigned long)SPI0Handler; /* set interrupt vector */
> VICVectCntl3 = 0x00000020 | 10;
> VICIntEnable |= 0x00000400; // 10 th bit to enable SPI0
> S0SPCR = 0x00A8; //8 bits per transfer,interrupt enable, master //for SPI flash
>
>#endif
> return;
>}
>/*******************************************************************
>* Name: Flash_Test
>* Desc: to test the spi flash
>* Inputs: None
>* outputs: None
>* Remarks if any:
>*******************************************************************/
>Bool Flash_Test(void)
>{
> Bool Mem_flag= True;
> unsigned char *temp,SPI0Data[256],SPI0Add[3];
> unsigned char i;
> SPI0Add[0]=0x1;//10;
> SPI0Add[1]=0x2;//0;
> SPI0Add[2]=0x3;//0;
> for (i=0 ;i < 2; i++) // 256
> {
> SPI0Data[i] =0x0AA;
> }
> Flash_MemWrite(SPI0Data,SPI0Add,2); //256
> temp = Flash_MemRead(SPI0Add,2); //256
>
> for (i=0 ;i < 2; i++) //256
> {
> if(temp[i]!= 0x0AA)
> {
> Mem_flag = False;
> break;
> }
> }
> if(Mem_flag)
> {
> return True;
> }
> else
> {
> return False;
> }
>
>}
>/*******************************************************************
>* Name : main
>* Desc:
>* Inputs: None.
>* outputs: None.
>*
>*******************************************************************/
>int main(void)
>{
> Bool flash_flag;
> DefinePins(); /* Define Pinsel0,1;*/
> Spi_Init();
> VICDefVectAddr = (unsigned long)default_isr;
> flash_flag=Flash_Test();
>
> while(1);
>}
>please help me and let me know where I am missing.
>
>Thank you in advance
>

Hi all,

It is entering into ISR when I put a break point inside the ISR but it is not pushing any data on the SPI port pins.

it is not entering into ISR when I do step wise execution. the reason for this may be the time it is spending in ISR is lesser than the time required between the two step wise executions.

can anyone tell me why it is not pushing data on to the SPI port.

Thank you in advance,
--- In l..., phaneesh.siva@... wrote:
>
> Hi All,
> >the SPI code is working fine with keil simulator it is going to ISR whenever SPIF is set.
> >but when the same code is loaded to LPC 2294 hardware board it is not working
> >and indefinitely waiting for SPIF bit.
It seems that your code is directly waiting for SPIF. What happens to your wait loops if the SPIF is cleared in an interrupt routine?

> > while ( !(S0SPSR & SPIF) );

Given this type of code, I don't understand why you are using interrupts. You're not using them to transfer data and you absolutely don't want to use the ISR to clear the SPIF bit.

> > IOSET1= 0x00050000; /* to disable #CS1 and to pull up #Hold of SPI flash */
> >
> > IOCLR1= 0x00010000; /* to generate #CS1 of SPI flash*/
It seems to me that these sequential statements are too close together. Are you sure that #CS1 can be toggled so fast?
One other thought: Spin loops like your wait() functions sometimes get optimized away. After all, the compiler knows the loop doesn't do anything. You might define the loop variable as 'volatile' and hope that the compiler realizes it shouldn't optimize. You should also check the assembler output and make sure the code still exists.

And be careful when you turn on various optimization levels. Spin loops that work with no optimization can disappear with high optimization.

Another thing: The simulator isn't the hardware. It doesn't matter what the simulator thinks the code will do. Ultimately, the code needs to run on hardware.

Richard

Dear Mr. Richard,

Thank you very much for the reply

> > It seems that your code is directly waiting for SPIF. What happens to > > your wait loops if the SPIF is cleared in an interrupt routine?

> > while ( !(S0SPSR & SPIF) );

> > Given this type of code, I don't understand why you are using
> > interrupts. You're not using them to transfer data and you absolutely > > don't want to use the ISR to clear the SPIF bit.

I have checked the code by disabling the interrupt also i.e by feeding S0SPCR with 0x20, even in this case also it is waiting indefinitely for SPIF bit if do step wise execution.

in earlier case, It is entering into ISR when I put a break point inside the ISR and do continuous run.

in both cases whether interrupt is enabled or disabled
if I put break points at line 1 and line 3 of the following code and do continuous run, it is not waiting for SPIF bit and it is coming to line 3.

line1: S0SPDR = 0x06; /* to set write enable latch */
line2: while ( !(S0SPSR & SPIF) );
line3: Dummy = S0SPDR; /* Flush the RxFIFO */

what I understood from above is, it is pumping data into S0SPDR and interrupt also getting generated.
but the question is why it is not pumping any data on to the SPI port pins

in the evaluation board schematics 100K pull up resistors are used and I also did the same for my board after this also there is no improvement.

please tell me what else can be done to this to make it work

Thank you in advance