|
|
View previous topic :: View next topic |
Author |
Message |
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
18f25k50 usb hangs when selecting FVR channel of ADC |
Posted: Fri Aug 07, 2015 12:24 pm |
|
|
compiler: latest CCS 5.048
PC is Win7 running Putty
This one's driving me nuts. I finally narrowed it down to some kind of interaction between the USB and selecting the FVR channel of the ADC.
I looked at the lst and the FVR code looks fine. I can't imagine how that could interact with the USB, but if I run this little program it will run until the FVR is selected. On my machine the usb has just enough time to send the \r and move the cursor back, then hangs. I think the usb must be streaming the msg in the background while the PIC tries to execute the set_adc_channel(FVR_CHANNEL) instruction.
Am I missing something with my USB setup? I think it's all okay based on the example code and that it worked great during all of my testing until I tried to read the FVR channel. I'm intending to use the USB interrupt so I don't have to babysit the usb_task() in the main loop.
If I just can't use the FVR that's fine, but if there is some underlying problem that's gonna haunt me later I'd like to figure it out.
Any thoughts on what to try next?
Code: |
/************************* Includes ************************************/
//#include <ex_usb_common.h> // using local copy in project folder
#include <18F25K50.h>
#DEVICE ADC=10
// use the internal oscillator with active clock tuning to synch to USB clock
#use delay(int, clock=48MHz, USB_FULL, act=USB)
#fuses NOWDT
#include <usb_cdc.h> // located in CCS driver file directory
#include <string.h> // located in CCS driver file directory
/******************************** MAIN() **************************/
void main(void)
{
char Keypressed;
// init USB; wait for connect; setup & use USB interrupt
usb_init();
// init USB (non-blocking)
// usb_task() need to be called in your loop to finish USB initialization.
// usb_init_cs();
//*** setup adc
setup_adc(ADC_CLOCK_DIV_64 | ADC_TAD_MUL_8);
setup_adc_ports(sAN8 | sAN11 | sAN13);
//** setup FVR
setup_vref(VREF_1v024);
/***************************MAIN LOOP ************************/
while(1){
Keypressed = usb_cdc_getc();
printf(usb_cdc_putc,"\r\nsetting to 8");
set_adc_channel(8);
delay_ms(100);
printf(usb_cdc_putc,"\r\nsetting to 11");
set_adc_channel(11);
delay_ms(100);
printf(usb_cdc_putc,"\r\nsetting to 13");
set_adc_channel(13);
delay_ms(100);
printf(usb_cdc_putc,"\r\nsetting to 8");
set_adc_channel(8);
delay_ms(100);
printf(usb_cdc_putc,"\r\nsetting to 11");
set_adc_channel(11);
delay_ms(100);
printf(usb_cdc_putc,"\r\nsetting to 13");
set_adc_channel(13);
delay_ms(100);
printf(usb_cdc_putc,"\r\nsetting to FVR"); // hangs during this msg.
set_adc_channel(FVR_CHANNEL);
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Fri Aug 07, 2015 12:48 pm |
|
|
The obvious thing 'wrong', is you are not calling USB_task, and have long delays.
It may just be that it is reaching the point where the incoming buffers overflow. USB is always sending you messages, and your device needs to handle these.
Try selecting the FVR channel, then channel 13. If it then hangs on the channel 13 selection, the problem is USB handling, and nothing to do with the FVR. |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Fri Aug 07, 2015 12:57 pm |
|
|
I thought, in reading the comments of the usb example, that if I initialized the usb using the interrupt function that I didn't need to call usb_task(). That it was only needed if you used the polling mode in which case I would need to make sure it got serviced evey 1ms. I may be wrong about that, but again my program was much larger and doing a lot more with no problem til I tried to look at that pesky FVR channel.
It worked fine on my previous board that way and on this one until I tried to read the FVR channel. I added the delays just to make sure I wasn't somehow flooding the usb handler with characters. I will try reducing the delays to 1ms and rearranging the order - but I think i've been around that block before. |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Fri Aug 07, 2015 1:05 pm |
|
|
Ttelmah wrote: | The obvious thing 'wrong', is you are not calling USB_task, and have long delays.
It may just be that it is reaching the point where the incoming buffers overflow. USB is always sending you messages, and your device needs to handle these.
Try selecting the FVR channel, then channel 13. If it then hangs on the channel 13 selection, the problem is USB handling, and nothing to do with the FVR. |
I reduced the delays to 1ms and moved the FVR up and it still hangs at the FVR. The terminal line resets (\r) and that's all she wrote...literally.
Code: |
/************************* Includes ************************************/
//#include <ex_usb_common.h> // using local copy in project folder
#include <18F25K50.h>
#DEVICE ADC=10
// use the internal oscillator with active clock tuning to synch to USB clock
#use delay(int, clock=48MHz, USB_FULL, act=USB)
#fuses NOWDT
#include <usb_cdc.h> // located in CCS driver file directory
#include <string.h> // located in CCS driver file directory
/******************************** MAIN() **************************/
void main(void)
{
char Keypressed;
// init USB; wait for connect; setup & use USB interrupt
usb_init();
// init USB (non-blocking)
// usb_task() need to be called in your loop to finish USB initialization.
// usb_init_cs();
//*** setup adc
setup_adc(ADC_CLOCK_DIV_64 | ADC_TAD_MUL_8);
setup_adc_ports(sAN8 | sAN11 | sAN13);
//** setup FVR
setup_vref(VREF_1v024);
/***************************MAIN LOOP ************************/
while(1){
Keypressed = usb_cdc_getc();
printf(usb_cdc_putc,"\r\nsetting to 8");
set_adc_channel(8);
delay_ms(1);
printf(usb_cdc_putc,"\r\nsetting to 11");
set_adc_channel(11);
delay_ms(1);
printf(usb_cdc_putc,"\r\nsetting to 13");
set_adc_channel(13);
delay_ms(1);
printf(usb_cdc_putc,"\r\nsetting to 8");
set_adc_channel(8);
delay_ms(1);
printf(usb_cdc_putc,"\r\nsetting to FVR"); // hangs here after /r terminal cursor goes to beginning of line
set_adc_channel(FVR_CHANNEL);
printf(usb_cdc_putc,"\r\nsetting to 11");
set_adc_channel(11);
delay_ms(1);
printf(usb_cdc_putc,"\r\nsetting to 13");
set_adc_channel(13);
delay_ms(1);
printf(usb_cdc_putc,"\r\nsetting to FVR");
set_adc_channel(FVR_CHANNEL);
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Fri Aug 07, 2015 2:04 pm |
|
|
OK. It was worth checking.
If you not using interrupts, then usb_task has to be called fast enough to actually service the USB events. With interrupts this requirement disappears, but it still does certain 'housekeeping' tasks, and if lots of data arrives, or things are left unhandled, the USB handling can get into unexpected states. Hence it should always be called at a regular (but not mSec level) period.
I'll try compiling something with 5.048 and this tomorrow and see if I can see anything in the assembler 'untoward'.... |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Fri Aug 07, 2015 3:41 pm |
|
|
Hi,
I don't see you calling usb_task(); at all in your current code! It's got to be in your while(1) loop, so that it is called frequently by the code. _________________ John
If it's worth doing, it's worth doing in real hardware! |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Mon Aug 10, 2015 11:29 am |
|
|
Ttelmah wrote: | OK. It was worth checking.
If you not using interrupts, then usb_task has to be called fast enough to actually service the USB events. With interrupts this requirement disappears, but it still does certain 'housekeeping' tasks, and if lots of data arrives, or things are left unhandled, the USB handling can get into unexpected states. Hence it should always be called at a regular (but not mSec level) period.
|
Thanks for the more detailed explaination, T.
Is that true even though I'm USB powered and not using usb_init_cs() nor the connection sense? If so, I will use it. But it certainly wasn't clear to me in the USB section of the manual..
Quote: | If you use connection sense, and the usb_init_cs() for initialization, then you must periodically call this function... |
I am USB powered and use usb_init(), not usb_init_cs().
Any more tests on my end are now delayed as the customer took my one-and-only board to do some sensor testing - it does seem to work great as long as I don't select that adc channel. When I get it back I will dig into it some more. The more I think about it the more I think it must be somehow causing a reset or power glitch that causes a reset, or something. I don't have a lot of capacitance on the chip supply as there is a limit per usb spec and a requirement on Vusb pin.
Hey, here's a thought where I may have screwed up: I am powering off of USB to a 3V3 regulator which powers the PIC. The Pic is an 18F, not LF and I have a 4.7uF cap on the Vusb pin and the Vusb is not connected to Vdd. Could it be that I should be using the LF chip so the on board PIC regulator is disabled and then connecting the Vusb pin to 3V3? Maybe something subtle happens when I switch to that channel of the adc that disturbs the on board regulator (since it has no overhead) enough to disrupt the usb communications? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Aug 10, 2015 12:31 pm |
|
|
Your description is out of spec for the chip. The internal regulator on the F chip, requires 3.6v minimum to generate Vusb (from Microchip after I asked). The LF chip requires _you_ to feed 3.3v into Vusb.
Though Microchip does not say, other users have found it is OK to connect 3.3v into Vusb on the F chip _provided_ you can ensure that this pin can never go above Vdd.
Can say that selecting the internal Vref does not cause a problem with a chip with external power. |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Mon Aug 10, 2015 1:13 pm |
|
|
Ttelmah wrote: | Your description is out of spec for the chip...
|
Thanks T, I'll change that.
I remember I went back and forth on powering the PIC from Vusb. I was worried about ESD events from the cable and figured it was easier to find a vreg with a higher input range that gave me a reasonable window to fit a TVS into. So I'll just switch to the LF part and tie the pin to Vdd when I get the board back.
All things considered, the CCS implementation is still pretty clean and simple compared to the Microchip implementation I tried a few years back. I had this up and talking to the usb in no time. |
|
|
|
|
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
|