Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

SPI Misbehavior

SPI Misbehavior

2004-11-18 by Richard

I am putting togther simple SPI routines using an interrupt.  What I 
am see is that, if I put a breakpoint in the SPI ISR, I see the byte 
get spit out and the program breaks where it ought to.  
Pressing "go" repeatadly sends out more bytes.  If I remove the 
breakpoint I expect to see repeated bytes sent out but, alas, I do 
not, I see one byte transmitted and the PC is in the delay loop went 
I stop execution.

Keil uVision 3 (Using the KEIL ARM compiler)
Ulink
IAR Kickstart board

Thanks for the help

Richard


Code:

void VIC_setup (void)  {

  /* The SPI Interrupt is an IRQ   */
  VICIntSelect   &= ~0x400;
  /* Use slot 0 for SPI Interrupt  */
  VICVectCntl0 = 0x2A;
  /* Set address for of ISR in slot 0  */
  VICVectAddr0 = (unsigned long)SPI_IRQ;
  /* Enable SPI Interrupt  */			
  VICIntEnable   = 0x400;			
}

void SPI_IRQ (void) __irq {

  SPI_data = SPDR;		//read data register		
			
  SPINT        = 1;                         // Clear interrupt flag
  VICVectAddr = 0;                         // Acknowledge Interrupt

}

void SPI_setup (void)	
	{
		SPCCR = 200; 	//  spi rate
		SPCR = 0xA0;	// master mode, interrupt enabled
		dummy = SPSR;
	}
void IO_setup (void)//
	{
		IODIR = 0xff; // P0.0..7 defined as Outputs
	    PINSEL0 = 0x5500; // enable spi i/o	
	}

 unsigned char SPI_tfr(unsigned char SPI_data)
 	{
		unsigned char val;

		SPDR = SPI_data;
	
	}


int main (void) {

unsigned char pin;
unsigned long i;

	SPI_setup();
	IO_setup();
	VIC_setup();
 
	pin = 0;

	while (1) {
 
//	if (pin) IOSET = 0x20; else IOCLR = 0x20;

//	pin ^= 1;
	SPI_tfr(0xAA);
	for(i=0; i<3000; i++);	  //kill some time to allow SPI 
interrupt
	
	

	}
}

Re: SPI Misbehavior (An Update)

2004-11-19 by Richard

Adding a read of the status register (SPSR) to the ISR solves the 
problem.  Now to figure out why.......


Richard

--- In lpc2000@yahoogroups.com, "Richard" <richas@y...> wrote:
> 
> I am putting togther simple SPI routines using an interrupt.  What 
I 
> am see is that, if I put a breakpoint in the SPI ISR, I see the 
byte 
> get spit out and the program breaks where it ought to.  
> Pressing "go" repeatadly sends out more bytes.  If I remove the 
> breakpoint I expect to see repeated bytes sent out but, alas, I do 
> not, I see one byte transmitted and the PC is in the delay loop 
went 
Show quoted textHide quoted text
> I stop execution.
> 
> Keil uVision 3 (Using the KEIL ARM compiler)
> Ulink
> IAR Kickstart board
> 
> Thanks for the help
> 
> Richard
> 
> 
> Code:
> 
> void VIC_setup (void)  {
> 
>   /* The SPI Interrupt is an IRQ   */
>   VICIntSelect   &= ~0x400;
>   /* Use slot 0 for SPI Interrupt  */
>   VICVectCntl0 = 0x2A;
>   /* Set address for of ISR in slot 0  */
>   VICVectAddr0 = (unsigned long)SPI_IRQ;
>   /* Enable SPI Interrupt  */			
>   VICIntEnable   = 0x400;			
> }
> 
> void SPI_IRQ (void) __irq {
> 
>   SPI_data = SPDR;		//read data register		
> 			
>   SPINT        = 1;                         // Clear interrupt flag
>   VICVectAddr = 0;                         // Acknowledge Interrupt
> 
> }
> 
> void SPI_setup (void)	
> 	{
> 		SPCCR = 200; 	//  spi rate
> 		SPCR = 0xA0;	// master mode, interrupt enabled
> 		dummy = SPSR;
> 	}
> void IO_setup (void)//
> 	{
> 		IODIR = 0xff; // P0.0..7 defined as Outputs
> 	    PINSEL0 = 0x5500; // enable spi i/o	
> 	}
> 
>  unsigned char SPI_tfr(unsigned char SPI_data)
>  	{
> 		unsigned char val;
> 
> 		SPDR = SPI_data;
> 	
> 	}
> 
> 
> int main (void) {
> 
> unsigned char pin;
> unsigned long i;
> 
> 	SPI_setup();
> 	IO_setup();
> 	VIC_setup();
>  
> 	pin = 0;
> 
> 	while (1) {
>  
> //	if (pin) IOSET = 0x20; else IOCLR = 0x20;
> 
> //	pin ^= 1;
> 	SPI_tfr(0xAA);
> 	for(i=0; i<3000; i++);	  //kill some time to allow SPI 
> interrupt
> 	
> 	
> 
> 	}
> }

Re: SPI Misbehavior (An Update)

2004-11-19 by tom_laffey

Richard,

Regarding your earlier post, I was thinking in terms of delays added 
by breakpoints, or now reads.  In the code below, I see the dummy 
read in the SPI_setup() and not in SPI_IRQ().  I would have expected 
that a small delay between SPINT=1 and VICVectAddr=0 might have 
helped due to the timing differences between the 2 devices.

Aside from delays, I've seen this sort of thing when there is a 
posted write buffer involved.  If dummy is in SRAM, you've forced the 
eviction of whatever is there beforehand.  That's the only write 
buffer I know about on the LPC.  Is there posibly any buffering 
involved in the VPB bridge?


Tom


--- In lpc2000@yahoogroups.com, "Richard" <richas@y...> wrote:
> 
> Adding a read of the status register (SPSR) to the ISR solves the 
> problem.  Now to figure out why.......
> 
> 
> Richard
> 
> --- In lpc2000@yahoogroups.com, "Richard" <richas@y...> wrote:
> > 
> > I am putting togther simple SPI routines using an interrupt.  
What 
> I 
> > am see is that, if I put a breakpoint in the SPI ISR, I see the 
> byte 
> > get spit out and the program breaks where it ought to.  
> > Pressing "go" repeatadly sends out more bytes.  If I remove the 
> > breakpoint I expect to see repeated bytes sent out but, alas, I 
do 
> > not, I see one byte transmitted and the PC is in the delay loop 
> went 
> > I stop execution.
> > 
> > Keil uVision 3 (Using the KEIL ARM compiler)
> > Ulink
> > IAR Kickstart board
> > 
> > Thanks for the help
> > 
> > Richard
> > 
> > 
> > Code:
> > 
> > void VIC_setup (void)  {
> > 
> >   /* The SPI Interrupt is an IRQ   */
> >   VICIntSelect   &= ~0x400;
> >   /* Use slot 0 for SPI Interrupt  */
> >   VICVectCntl0 = 0x2A;
> >   /* Set address for of ISR in slot 0  */
> >   VICVectAddr0 = (unsigned long)SPI_IRQ;
> >   /* Enable SPI Interrupt  */			
> >   VICIntEnable   = 0x400;			
> > }
> > 
> > void SPI_IRQ (void) __irq {
> > 
> >   SPI_data = SPDR;		//read data register		
> > 			
> >   SPINT        = 1;                         // Clear interrupt 
flag
> >   VICVectAddr = 0;                         // Acknowledge 
Interrupt
Show quoted textHide quoted text
> > 
> > }
> > 
> > void SPI_setup (void)	
> > 	{
> > 		SPCCR = 200; 	//  spi rate
> > 		SPCR = 0xA0;	// master mode, interrupt enabled
> > 		dummy = SPSR;
> > 	}
> > void IO_setup (void)//
> > 	{
> > 		IODIR = 0xff; // P0.0..7 defined as Outputs
> > 	    PINSEL0 = 0x5500; // enable spi i/o	
> > 	}
> > 
> >  unsigned char SPI_tfr(unsigned char SPI_data)
> >  	{
> > 		unsigned char val;
> > 
> > 		SPDR = SPI_data;
> > 	
> > 	}
> > 
> > 
> > int main (void) {
> > 
> > unsigned char pin;
> > unsigned long i;
> > 
> > 	SPI_setup();
> > 	IO_setup();
> > 	VIC_setup();
> >  
> > 	pin = 0;
> > 
> > 	while (1) {
> >  
> > //	if (pin) IOSET = 0x20; else IOCLR = 0x20;
> > 
> > //	pin ^= 1;
> > 	SPI_tfr(0xAA);
> > 	for(i=0; i<3000; i++);	  //kill some time to allow SPI 
> > interrupt
> > 	
> > 	
> > 
> > 	}
> > }

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.