Reply by rtstofer August 29, 20112011-08-29
--- In l..., "rtstofer" wrote:
>
> It acknowledges that the active interrupt is complete. The VIC knows which interrupt is active so it isn't necessary to specify which interrupt to acknowledge.
I omitted the part where the ISR must clear the appropriate interrupt flag in the peripheral that is being serviced. It is not sufficient to simply acknowledge the intterupt for the VIC.

There may be a number of interrupt flags in any given peripheral. Your ISR has to handle all possibilities and clear each of the individual flags.

If you don't clear the flag(s) in the peripheral, you will get another interrupt.

Some flags are cleared automatically when certain registers are read. Read over the section on UART0 and look at table 105. The right column shows how each potential interrupt is cleared. None of them require deliberate writing of a register bit to clear a flag.

Richard

An Engineer's Guide to the LPC2100 Series

Reply by David Smead August 29, 20112011-08-29
Interrupts allow your program to handle events faster than polling all
possible events to handle them.

DaveS

On Mon, Aug 29, 2011 at 6:48 AM, lucky_suhas wrote:

> **
>
> thanks, is it necessary i use interrupts in my code? not only in this case,
> i am asking in general. Most of the codes that i have come across for
> UART,SPI,I2C, EEPROM, etc., have made use of interrupts.
> is it just a better programming technique or is it a necessary one?
>
> --- In l..., "rtstofer" wrote:
> >
> >
> >
> > --- In l..., "lucky_suhas" wrote:
> > >
> > > HI again,
> > >
> > > I have been trying to learn programming using the LPC2148.
> > > Thanks to all the people who replied and helped with my ADC code.
> > > I am taking the help of some example codes i found online. but with
> regard to SPI there doesn't seem to be any examples around. although i found
> one that interfaces SPI to SD card. it was a little difficult to understand.
> i would like a generalized code on using SPI.
> > >
> > > i am not asking you to give me the code.. if anyone could suggest me on
> the various functions that i should write and the process flow. like in ADC
> i had to write two functions
> > > 1.initialization the control register
> > > 2.then i had to read the data register.
> >
> >
> >
> >
> > For SPI to work, you send a byte or short (8 or 16 bit) out while the
> hardware simultaneously clocks in a similar data item.
> >
> > The following code is set up for 16 bit transfers. SPI0_send sends out a
> 16 bit unsigned short and returns the unsigned short that was clocked in.
> >
> > #include "lpc214x.h"
> > #include "spi.h"
> >
> > /*
> > * P0.4 => SCK connect to AD7327 SCLK
> > * P0.5 => MISO connect to AD7327 DOUT
> > * P0.6 => MOSI connect to AD7327 DIN
> > * P0.7 => SSEL connect to AD7327 CS'
> > */
> >
> > #define SSEL (1 << 7)
> > #define SPI_SPIE (0x00000080)
> > #define SPI_LSBF (0x00000040)
> > #define SPI_MSTR (0x00000020)
> > #define SPI_CPOL (0x00000010)
> > #define SPI_CPHA (0x00000008)
> > #define SPI_BitEnable (0x00000004)
> > #define SPI_Bits (0x00000000)
> >
> > #define SPI_SPIF (0x00000080)
> >
> > #define SPI_DIVIDER (8)
> >
> > /*
> > * Set up SPI0 as a master with CPOL = 1, CPHA = 0 and 16 bit transfers.
> > * Force P0.7 to GPIO, set it for output and set it high
> > */
> > void SPI0_init(void)
> > {
> > PINSEL0 |= 0x00001500;
> > PINSEL0 &= ~0x0000C000;
> > IOSET0 = SSEL;
> > IODIR0 |= SSEL;
> >
> > S0SPCR = SPI_MSTR | SPI_CPOL | SPI_BitEnable | SPI_Bits;
> > S0SPCCR = SPI_DIVIDER;
> > }
> >
> > /*
> > * Send value to ADC and return value shifted in.
> > */
> > unsigned short SPI0_Send(const unsigned short value)
> > {
> > IOCLR0 = SSEL;
> > S0SPDR = value;
> > while (!(S0SPSR & SPI_SPIF))
> > ;
> > IOSET0 = SSEL;
> > return (S0SPDR);
> > }
> >
> > You can always just connect MOSI and MISO externally (a jumper wire) and
> test by looking at what is received versus what it sent. They should be
> identical.
> >
> > Richard
> >
>
Reply by rtstofer August 29, 20112011-08-29
--- In l..., "lucky_suhas" wrote:
> so what an interrupt would do is to carryout the ISR in the background while the rest of the code execution continues?

A timer interrupt might increment a clock or it might be a time tick for an RTOS.

A character received interrupt might grab the char from the UART and stick it in a circular buffer. The main program would simply grab chars from the circular buffer rather than deal with the UART.

A character output interrupt might grab a character from a circular buffer and send it out over a serial port. The main program would simply stuff characters into the buffer rather than concern itself with handling the UART.

And so on...

>
> regarding the ISR address:
>
> i have noticed
> 1. VICVectAddr=0;
> /*is used at the end of the code to reset the VIC in the __irq*/
>
> 2. VICVectAddr0= (unsigned int) &name_of_ISR;
> /* is used in the initialization of the particular function*/
>
> in point 1. what is the meaning of resetting the VIC? addr register is only to store the ISR address and more over it should have a suffix of 0-15, right?

It acknowledges that the active interrupt is complete. The VIC knows which interrupt is active so it isn't necessary to specify which interrupt to acknowledge.

Remember that the VIC is a priority based controller. This is important once interrupt nesting is enabled.

It's also worth knowing that nested interrupts are a problem unless you write some additional 'wrapper' code (usually in crt.s) to handle the nesting. Don't worry about it right now because it won't happen. Once an interrupt is started, further interrupts are disabled so even higher priority interrupts are ignored. -- remember this! --

There are (or at least, were) problems with the GNU toolchain and interrupt code. Once you find out how to write the interrupt wrapper in crt.s, you won't use any special __attributes__ when you write the handler. All handlers will be ordinary C functions. This is VERY NICE and worth the cost of researching wrappers.

Here is some reference material:
http://www.nxp.com/documents/application_note/AN10381.pdf

You can search the group archives for 'wrapper'. Code is available around here somewhere because that's where I got it.

But you only need it if you decide to use nested interrupts and those are usually only required if you actually use the priority scheme.
>
> in point 2. why is it necessary the data type be given? is it possible the compiler might assign a different type to a Lvalue of the function?
Probably not but C programmers are a paranoid bunch (with very good reason). It is better to tell the compiler what to do than try to find out what it did. It's called 'defensive programming'. Of course you could simply eliminate the cast and see what happens. Maybe the compiler will generate a warning or an error. But that might depend on compiler switches... It's better to use the cast.

Richard

Reply by Donald H August 29, 20112011-08-29
--- In l..., "lucky_suhas" wrote:
> so what an interrupt would do is to carryout the ISR in the background while the rest of the code execution continues?
Foreground and Background are from the point of view of the main task.

If you are talking to someone, you may consider that the Foreground task.

Some else comes along and taps you on the shoulder, you SUSPEND the main task and SERVICE the Background task.

If you spend too much time on the Background task, the Foreground task may crash (walk away).

After you finish with the Background task, you RESUME the foreground task.

As a beginner I would suggest not using Interrupts until you have written code for all the peripherals on the CPU you are using.

The LPC family is fast enough to use without any interrupts.
( even most 8-bit processors are fast enough )

Once you have learned how to use them, adding interrupts will be much easier.

don

Reply by Kevin August 29, 20112011-08-29
When an interrupt is triggered the ISR is run. The ISR is not run in the background, it "pauses" the normal code and runs the ISR. When the ISR returns the normal code resumes.

--- In l..., "lucky_suhas" wrote:
> so what an interrupt would do is to carryout the ISR in the background while the rest of the code execution continues?
>
> regarding the ISR address:
>
> i have noticed
> 1. VICVectAddr=0;
> /*is used at the end of the code to reset the VIC in the __irq*/
>
> 2. VICVectAddr0= (unsigned int) &name_of_ISR;
> /* is used in the initialization of the particular function*/
>
> in point 1. what is the meaning of resetting the VIC? addr register is only to store the ISR address and more over it should have a suffix of 0-15, right?
>
> in point 2. why is it necessary the data type be given? is it possible the compiler might assign a different type to a Lvalue of the function?
>
> --- In l..., "rtstofer" wrote:
> >
> >
> >
> > --- In l..., "lucky_suhas" wrote:
> > >
> > >
> > > thanks, is it necessary i use interrupts in my code? not only in this case, i am asking in general. Most of the codes that i have come across for UART,SPI,I2C, EEPROM, etc., have made use of interrupts.
> > > is it just a better programming technique or is it a necessary one?
> > >
> >
> > No, you don't need to use interrupts. But if you don't, you will spend a lot of compute cycles waiting in loops and not doing other stuff. This may not be important at this point in your learning cycle.
> >
> > Once you start developing more advanced programs, you will want to use interrupts and I/O buffers. When you get around to using an RTOS (Real Time Operating System), you will have to use interrupts.
> >
> > Nevertheless, you can write a lot of programs before you have to worry about interrupts.
> >
> > All that said, your first step into interrupts will probably be serial input. By definition, that input is asynchronous to your program and you can't predict when a character will come along. In many applications your program depends on the next character and it can just wait or, perhaps, check for character availability from time to time. But, sooner or later, you will want the arrival of a character to just notify your program of its arrival.
> >
> > The next step will probably be character output. You won't want your application waiting around to send a series of chars out the serial port. You will want to stick them in an output buffer and let the serial port interrupt routine handle sending them along.
> >
> > The programs you see that use interrupts were written for performance. You will get there...
> >
> > Richard
>

Reply by lucky_suhas August 29, 20112011-08-29
so what an interrupt would do is to carryout the ISR in the background while the rest of the code execution continues?

regarding the ISR address:

i have noticed
1. VICVectAddr=0;
/*is used at the end of the code to reset the VIC in the __irq*/

2. VICVectAddr0= (unsigned int) &name_of_ISR;
/* is used in the initialization of the particular function*/

in point 1. what is the meaning of resetting the VIC? addr register is only to store the ISR address and more over it should have a suffix of 0-15, right?

in point 2. why is it necessary the data type be given? is it possible the compiler might assign a different type to a Lvalue of the function?

--- In l..., "rtstofer" wrote:
>
> --- In l..., "lucky_suhas" wrote:
> >
> >
> > thanks, is it necessary i use interrupts in my code? not only in this case, i am asking in general. Most of the codes that i have come across for UART,SPI,I2C, EEPROM, etc., have made use of interrupts.
> > is it just a better programming technique or is it a necessary one?
> > No, you don't need to use interrupts. But if you don't, you will spend a lot of compute cycles waiting in loops and not doing other stuff. This may not be important at this point in your learning cycle.
>
> Once you start developing more advanced programs, you will want to use interrupts and I/O buffers. When you get around to using an RTOS (Real Time Operating System), you will have to use interrupts.
>
> Nevertheless, you can write a lot of programs before you have to worry about interrupts.
>
> All that said, your first step into interrupts will probably be serial input. By definition, that input is asynchronous to your program and you can't predict when a character will come along. In many applications your program depends on the next character and it can just wait or, perhaps, check for character availability from time to time. But, sooner or later, you will want the arrival of a character to just notify your program of its arrival.
>
> The next step will probably be character output. You won't want your application waiting around to send a series of chars out the serial port. You will want to stick them in an output buffer and let the serial port interrupt routine handle sending them along.
>
> The programs you see that use interrupts were written for performance. You will get there...
>
> Richard
>

Reply by rtstofer August 29, 20112011-08-29
--- In l..., "lucky_suhas" wrote:
> thanks, is it necessary i use interrupts in my code? not only in this case, i am asking in general. Most of the codes that i have come across for UART,SPI,I2C, EEPROM, etc., have made use of interrupts.
> is it just a better programming technique or is it a necessary one?
>

No, you don't need to use interrupts. But if you don't, you will spend a lot of compute cycles waiting in loops and not doing other stuff. This may not be important at this point in your learning cycle.

Once you start developing more advanced programs, you will want to use interrupts and I/O buffers. When you get around to using an RTOS (Real Time Operating System), you will have to use interrupts.

Nevertheless, you can write a lot of programs before you have to worry about interrupts.

All that said, your first step into interrupts will probably be serial input. By definition, that input is asynchronous to your program and you can't predict when a character will come along. In many applications your program depends on the next character and it can just wait or, perhaps, check for character availability from time to time. But, sooner or later, you will want the arrival of a character to just notify your program of its arrival.

The next step will probably be character output. You won't want your application waiting around to send a series of chars out the serial port. You will want to stick them in an output buffer and let the serial port interrupt routine handle sending them along.

The programs you see that use interrupts were written for performance. You will get there...

Richard

Reply by lucky_suhas August 29, 20112011-08-29
thanks for that link. it helped a lot!

--- In l..., roelof 't Hooft wrote:
>
> On Sun, 2011-08-28 at 14:26 +0000, lucky_suhas wrote:
> > i am not asking you to give me the code.. if anyone could suggest me
> > on the various functions that i should write and the process flow.
>
> Hi,
>
> Almost on the bottom of this page :
> http://www.nxp.com/#/pip/pip=[pip=LPC2141_42_44_46_48]|
> pp=[t=pip,i=LPC2141_42_44_46_48]
>
> you will find this link "LPC2xxx SPI master code example" :
>
> http://www.nxp.com/documents/other/MACC06001_LPC2000_SPI.pdf
>
> There is more what you might want to look at.
>
> roelof
>

Reply by lucky_suhas August 29, 20112011-08-29
its a bit difficult to follow or maybe its just me. of course once i learn what i am doing it might just be helpful. thanks!

--- In l..., "rtstofer" wrote:
>
> --- In l..., "lucky_suhas" wrote:
> >
> > HI again,
> >
> > I have been trying to learn programming using the LPC2148.
> > Thanks to all the people who replied and helped with my ADC code.
> > I am taking the help of some example codes i found online. but with regard to SPI there doesn't seem to be any examples around. although i found one that interfaces SPI to SD card. it was a little difficult to understand. i would like a generalized code on using SPI.
> >
> > i am not asking you to give me the code.. if anyone could suggest me on the various functions that i should write and the process flow. like in ADC i had to write two functions
> > 1.initialization the control register
> > 2.then i had to read the data register.
> >
> > i'll give it a try and get back to you for your suggestions.
> >
> > also any suggestions or tips on things to keep an eye out for while using UART.
> > Thanks for reading!
> >
> Everything you could possibly need to know about the LPC2148 is available at www.jcwren.com/arm
>
> Much of the code is wrapped around FreeRTOS (a real-time operating system) but you can easily see how each peripheral is used. JC did a great job with this code.
>
> I use it for reference whenever I begin a project with the LPC2148.
>
> Richard
>

Reply by lucky_suhas August 29, 20112011-08-29
thanks, is it necessary i use interrupts in my code? not only in this case, i am asking in general. Most of the codes that i have come across for UART,SPI,I2C, EEPROM, etc., have made use of interrupts.
is it just a better programming technique or is it a necessary one?

--- In l..., "rtstofer" wrote:
>
> --- In l..., "lucky_suhas" wrote:
> >
> > HI again,
> >
> > I have been trying to learn programming using the LPC2148.
> > Thanks to all the people who replied and helped with my ADC code.
> > I am taking the help of some example codes i found online. but with regard to SPI there doesn't seem to be any examples around. although i found one that interfaces SPI to SD card. it was a little difficult to understand. i would like a generalized code on using SPI.
> >
> > i am not asking you to give me the code.. if anyone could suggest me on the various functions that i should write and the process flow. like in ADC i had to write two functions
> > 1.initialization the control register
> > 2.then i had to read the data register.
> For SPI to work, you send a byte or short (8 or 16 bit) out while the hardware simultaneously clocks in a similar data item.
>
> The following code is set up for 16 bit transfers. SPI0_send sends out a 16 bit unsigned short and returns the unsigned short that was clocked in.
>
> #include "lpc214x.h"
> #include "spi.h"
>
> /*
> * P0.4 => SCK connect to AD7327 SCLK
> * P0.5 => MISO connect to AD7327 DOUT
> * P0.6 => MOSI connect to AD7327 DIN
> * P0.7 => SSEL connect to AD7327 CS'
> */
>
> #define SSEL (1 << 7)
> #define SPI_SPIE (0x00000080)
> #define SPI_LSBF (0x00000040)
> #define SPI_MSTR (0x00000020)
> #define SPI_CPOL (0x00000010)
> #define SPI_CPHA (0x00000008)
> #define SPI_BitEnable (0x00000004)
> #define SPI_Bits (0x00000000)
>
> #define SPI_SPIF (0x00000080)
>
> #define SPI_DIVIDER (8)
>
> /*
> * Set up SPI0 as a master with CPOL = 1, CPHA = 0 and 16 bit transfers.
> * Force P0.7 to GPIO, set it for output and set it high
> */
> void SPI0_init(void)
> {
> PINSEL0 |= 0x00001500;
> PINSEL0 &= ~0x0000C000;
> IOSET0 = SSEL;
> IODIR0 |= SSEL;
>
> S0SPCR = SPI_MSTR | SPI_CPOL | SPI_BitEnable | SPI_Bits;
> S0SPCCR = SPI_DIVIDER;
> }
>
> /*
> * Send value to ADC and return value shifted in.
> */
> unsigned short SPI0_Send(const unsigned short value)
> {
> IOCLR0 = SSEL;
> S0SPDR = value;
> while (!(S0SPSR & SPI_SPIF))
> ;
> IOSET0 = SSEL;
> return (S0SPDR);
> }
>
> You can always just connect MOSI and MISO externally (a jumper wire) and test by looking at what is received versus what it sent. They should be identical.
>
> Richard
>