--- In lpc2000@yahoogroups.com, Sten <list@n...> wrote:
>
> ee_gary wrote:
> > Long time lurker, first time poster...
> >
> > I've set the SPIE bit in the Control Register. I can see the SPIF bit
> > get set in the Status Register. However, I do NOT see the SPI
> > Interrupt bit get set in the Interrupt Register. Shouldn't this occur
> > as soon as the SPIF bit is set, regardless of how the VIC is set up?
> > I have the VIC set up "correctly", but the ISR never executes
> > (presumably because the SPI Interrupt never fires). I've had
> > interrupts working correctly for UART0 and a timer, so I know that
> > interrupts can work (they just aren't in this occasion).
> >
> > I can do non-interrupt SPI transmits (i.e. the 1st byte of an
> > interrupt-based multibye transfer) so I know the hardware is ok (SSEL
> > = 1). I've duplicated this on the MCB2130 and a LPC2214 dev board.
> >
> > Any insight from those that have implemented interrupt based SPI is
> > appreciated.
> >
> > Stumped in Seattle...
> >
>
> Please can you send a small portion of source code? It sounds
unbelievable.
>
> Sten
>
> --
> /************************************************
> Do you need a tiny and efficient real time
> operating system (RTOS) with a preemtive
> multitasking for LPC2000 or AT91SAM7?
>
> http://nanortos.net-attack.de/
>
> Or some open-source tools and code for LPC2000?
>
> http://www.net-attack.de/
>
> ************************************************/
>
It'd be my pleasure. Here's the init function:
void spi0Init(void)
{
// Set port pins for SPI0
PINSEL0 = (PINSEL0 & ~S0_PINMASK) | S0_PINSEL;
// Set SPI Registers
S0SPCR = 0; // Clear all bits
S0SPCR |= SPCR_CPHA; // Data sampled on rising edge
S0SPCR |= SPCR_CPOL; // SCK active low
S0SPCR |= SPCR_MSTR; // Master mode
S0SPSR; // Cleared by a read of this register
S0SPDR; // Cleared by a read of this register
S0SPCCR = 128; // 8 is max speed
S0SPINT = 1; // Cleared by writing a 1 to it
// initialize the interrupt vector
VICIntSelect = 0; // Select IRQ
VICIntEnable = 0x00000400;
VICVectAddr0 = (unsigned long)spi0ISR;
VICVectCntl0 = 0x0000002A;
// initialize the transmit data queue
spi0_tx_extract_idx = spi0_tx_insert_idx = 0;
spi0_tx_running = 0;
}
and the transmit function:
int spi0Putch(int ch)
{
uint16_t temp;
unsigned cpsr;
temp = (spi0_tx_insert_idx + 1) % SPI0_TX_BUFFER_SIZE;
if (temp == spi0_tx_extract_idx)
return -1; // no room
cpsr = disableIRQ(); // disable global interrupts
S0SPCR &= ~SPCR_SPIE; // disable TX interrupts
restoreIRQ(cpsr); // restore global interrupts
// check if in process of sending data
if (spi0_tx_running){
// add to queue
spi0_tx_buffer[spi0_tx_insert_idx] = (uint8_t)ch;
spi0_tx_insert_idx = temp;
}
else{
// set running flag and write to output register
spi0_tx_running = 1;
S0SPDR = (uint8_t)ch;
}
cpsr = disableIRQ(); // disable global interrupts
S0SPCR |= SPCR_SPIE; // enable TX interrupts
restoreIRQ(cpsr); // restore global interrupts
return (uint8_t)ch;
}
and finally, the ISR that never fires...
void spi0ISR(void)
{
// perform proper ISR entry so thumb-interwork works properly
ISR_ENTRY();
// check if more data to send
if (spi0_tx_insert_idx != spi0_tx_extract_idx){
S0SPDR = spi0_tx_buffer[spi0_tx_extract_idx++];
spi0_tx_extract_idx %= SPI0_TX_BUFFER_SIZE;
}
else{ // No more to transmit
S0SPCR &= ~SPCR_SPIE;
spi0_tx_running = 0;
}
S0SPINT = 1;
VICVectAddr = 0x00000000;
ISR_EXIT();
}
It seems like it should be something simple. Everything looks okay,
but the ISR never fires.
Thanks,
GaryMessage
Re: SPI Interrupt not firing?
2005-10-12 by ee_gary
Attachments
- No local attachments were found for this message.