|
|
View previous topic :: View next topic |
Author |
Message |
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
interrupt based timer + USB |
Posted: Fri Nov 09, 2007 6:25 am |
|
|
I was wondering if it is possible for USB and timer interrupts to co-exist. Very quickly I'll tell you what I'm attempting to do. I need to sample values from three ADC channels, perform a little simple math on the values and display these values on seven segment displays. Simultaneously, every half second I need to output these values through USB to a terminal program.
I've got the ADC working, and I've also been able to send the values at APPROXIMATELY 1 second over USB CDC. However, I need to send data at PRECICELY 1 second intervals. So I tried to use timer1 to generate interrupts at a fixed time interval. I'd have the USB routine in the timer1 ISR.
The problem I'm facing is that (I think) CCS disables the timer1 interrupt when it starts servicing it (ie the timer1 ISR). I dont really know how long USB takes to send data (8 bytes over CDC, to be precise), so I can't even put in a 'set_timer1(adjustment)' statement.
Help would be appreciated very much.
I'm running an 18F2550 at 48MHz (20MHz crystal with PLL). To make matters a little more complicated, I also have the Microchip bootloader.
I've taken care of the '#build (reset=0x800, interrupt=0x808)' and similar statements, and I have also got each sub-part to work individually. However integrating them seems to be a problem. I'm still a newbie to the 18 series and USB, so if there's something technically wrong in the above, my apologies.
Thanks,
Rohit |
|
|
Foppie
Joined: 16 Sep 2005 Posts: 138 Location: The Netherlands
|
|
Posted: Fri Nov 09, 2007 7:56 am |
|
|
I don't know for sure, but you can try setting your clock to just 20 MHz (disable PLL).
I thought it wasn't possible to multiply a 20MHz crystal with a PIC. I thought only crystals up to 12 MHz could be multiplied. But I might be wrong!
Hope this helps |
|
|
Ttelmah Guest
|
|
Posted: Fri Nov 09, 2007 9:05 am |
|
|
On the USB pics, the 'PLL', is a very different beasty.
On these, there is a programmable divider then a *24PLL (as opposed to the *4 standard on the other chips), then an /2 divider, to feed the USB (which wants 48MHz) and another programmable divider that can be fed from eiher this signal, or the original clock...
You cant run without the PLL on the USB chips and use USB. It is _needed_ to get the 48MHz for the USB.
First, you could consider triggering the ADC, from the CCP interrupt. This will trigger the ADC, at exactly a time, and then you could use the ADC 'complete' interrupt to read the value. If the reading is slightly delayed, this wouldn't matter,since the actual samlping by the ADC will have happened at exactly the required time.
Other possibility, use the high priority interrupt for the timer, _but_ you then need to be fully aware, that you must not take too long in the interrupt, or you _will_ cause problems with the USB.
Best Wishes |
|
|
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Fri Nov 09, 2007 10:40 pm |
|
|
Thanks for the quick replies.
Foppie, I can't run a 20MHz crystal because, as Ttelmah pointed out, I won't have USB. Also, I need the speed for the math and display updating, so I wouldn't want to run at any slower rate than 48MHz/4.
Ttelmah, wow! I didn't realize that the PLL is so complicated. Anyway, I will try the ADC interrupts. The problem with the high priority interrupts is that USB is a high priority interrupt itself. I don't want to mess with the USB communication. All the same, I will try. Give me a few days. I'll get some code up, and if I have a problem I know I can turn here :-).
Thanks again.
Rohit |
|
|
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Fri Nov 09, 2007 10:44 pm |
|
|
Oh, would anyone know how long (approximately) a USB CDC transmission takes? I need to send 8 bytes (ASCII characters). I can't simulate the USB statements in MPLAB ('usb_task()', 'usb_cdc_putc()', etc) so I don't really know how to calculate the time the transmission takes. I know its fast, but how fast?
Rohit |
|
|
Ttelmah Guest
|
|
Posted: Sat Nov 10, 2007 3:49 am |
|
|
The USB interrupt, does not use the high priority ability in the standard code. They call the putc routine 'fast', but this is not the 'fast' keyword, needed to change the priority. You can have a higher priority interrupt, but as warned, the caveat is the time taken in this must be short.
Things to think about. On the ADC, the slwest thing is the time taken to charge the capacitor iternally to the required voltage. So (for instance), it is a 'good' idea to select the next required channel, before leaving the interrupt, so that on the next interrupt, the capacitor is already charged to the required voltage (to avoid having to wait for this in the handler). Similarly, you can trigger the conversion, then on another interrupt, perform the actual reading, which is then only a couple of machine cycles.
You should be fine, using a high priority timer interrupt to read the ADC, provided you keep it sort. USB itself, allows a maximum of 10mSec latency on a device response, and provided this is kept well clear of, everything should be OK.
Remember the transmission is done by the hardware. It'll 'take' just over 5uSec (for 8 bytes), but won't happen, till the master device, polls you. You should be polled at no more than 1mSec intervals, but this is dependant on what else is happening on the USB bus. You don't wait for the transmission to complete, this is the whole point of the interrupt dven approach
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|