|
|
View previous topic :: View next topic |
Author |
Message |
madtoilet
Joined: 02 Apr 2008 Posts: 36
|
USB_serial confusion |
Posted: Tue Jul 15, 2008 2:55 pm |
|
|
Hi, I'm back. I'm working with the PIC18F4550. I'm using the USB_SERIAL example provided with no modification. I'm encountering various problems however.
1. it's giving me a problem with interrupt re-entrancies.
2. I'm not sure how to connect the USB to the PC and have the PC detect it.
I've done some forum searches but i'm still unable to find out how this works.
I might have missed some topics though. If anyone recalls a topic similar to mine if you could provide a link or some advice i'd greatly appreciate it.
Thanks in advance |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah Guest
|
|
Posted: Wed Jul 16, 2008 3:22 am |
|
|
PCM, has covered the re-entrancy part.
On getting it seen, sequence is:
1) If your hardware does not match the example, select different pin for the USB power detection if needed, or disable this if you are not using it.
2) Check the fuses for the clock _carefully_. You need a crystal, that is a multiple of 4Mhz. Allowable multiples are:
1, 2, 3, 4, 5, 6, 10, & 12
The last two require an external oscillator, rather than a crystal.
Change the 'PLLx' fuse to select the multiple your crystal is.
Get your crystal loading capacitance close to right. Allow for the track, and pin capacitance of the board. USB requires quite an accurate clock.
3) Be rather careful of the capacitance on Vusb. The '220nF' in the data sheet, is a _minimum_, and there can be problems, with some capacitor types having a wide tolerance, giving just slight reliability problems here. I use 1uF electrolytic, in parallel with 0.1uF ceramic, or a single 0.47uF polyester, and these have been reliable in a lot of situations.
4) Quadruple check your D+/D- wiring - it is surprisingly common to connect these the wrong way round (been a couple of threads here with this).
5) Be careful about the connections to these pins, Remember USB, is a high frequency bus, and it is unlikely to work if you start using simple 'breadboard' techniques here.
6) Look at section 17.6 on the data sheet, for how to supply power.
With the correct frequency selected, the supplied demo, should be 'seen' straight away if the power is sorted, when plugged onto the USB bus.
Start with this, modifying only the bits you 'must', before trying to get your own stuff working.
Best Wishes |
|
|
madtoilet
Joined: 02 Apr 2008 Posts: 36
|
|
Posted: Fri Jul 18, 2008 4:13 pm |
|
|
thank you very very much guys, you've been great help, yet again!
i got it to detect on the PC but i have a question about the drivers for it. Windows is requesting a driver here but i'm stumped. Where do i get the drivers for this device? The example tells me that windows should have the drivers for this but my windows (vista) and my team mate's windows (xp) do not have the drivers for this.
Any advice ? |
|
|
Ttelmah Guest
|
|
Posted: Sat Jul 19, 2008 4:19 am |
|
|
Classic 'Windows'.
It actually just needs the .INF file to tell it to use the drivers it already has. There are a number (for different OS's), in the drivers directory of your CCS installation.
Why Windows calls this a 'driver', is a mystery...
If you are using Vista, make sure you copy the Vista version (cdc_NTXPVista.inf), into a _different_ directory, and then point the install at this. Otherwise, Vista will automatically 'find' the XP version, and then not work....
Best Wishes |
|
|
madtoilet
Joined: 02 Apr 2008 Posts: 36
|
|
Posted: Tue Jul 22, 2008 10:24 am |
|
|
i think we got it to work. Windows is seeing the device now. thanks again guys |
|
|
madtoilet
Joined: 02 Apr 2008 Posts: 36
|
|
Posted: Tue Jul 22, 2008 4:13 pm |
|
|
ho ho ho! ok. We got the USB to work but now i am trying to get it to work with my GSM unit. I'm still grasping the serial usb example. I have a code like such:
Code: | //#include "H:\Senior Project\usb serial\ex_usb_serial.h"
// #include <math.h>
// #include <stdlib.h>
//set to 1 to use a PIC's internal USB Peripheral
//set to 0 to use a National USBN960x peripheral
#define __USB_PIC_PERIF__ 1
#if !defined(__PCH__)
#error USB CDC Library requires PIC18
#endif
#DEFINE LED1 PIN_A5
#include <18F4550.h>
#include <string.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
/////////////////////////////////////////////////////////////////////////////
//
// If you are using a USB connection sense pin, define it here. If you are
// not using connection sense, comment out this line. Without connection
// sense you will not know if the device gets disconnected.
// (connection sense should look like this:
// 100k
// VBUS-----+----/\/\/\/\/\----- (I/O PIN ON PIC)
// |
// +----/\/\/\/\/\-----GND
// 100k
// (where VBUS is pin1 of the USB connector)
//
/////////////////////////////////////////////////////////////////////////////
///only the 18F4550 development kit has this pin
/*
#if __USB_PIC_PERIF__ && defined(__PCH__)
#define USB_CON_SENSE_PIN PIN_B2
#endif
*/
#include <usb_cdc.h>
/////////////////////////////////////////////////////////////////////////////
//
// Configure the demonstration I/O
//
/////////////////////////////////////////////////////////////////////////////
#define LED2 PIN_B4
#define LED3 PIN_B5
#DEFINE BUTTON PIN_A4
#define LED_ON output_low
#define LED_OFF output_high
#byte RCREG = 0x1A
#define BUFFER_SIZE 80
char inStr[BUFFER_SIZE];
char char_rcvd;
char done = 1;
//int cursor=0x80;
int i=0;
int sentence= 0;
void out_LCD(int i);
void receive_text(void);
void int_LCD(void);
void cursor_position(int position);
void out_LCD_string(char *string);
void clear(void);
//char number[11]="5 ";
//byte num[] ="5104682725";
char temp[70] = " ";
#int_rda
void serial_isr() {
#use rs232(baud=4800,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, stream=GSM,ERRORS)
output_b(0x02);
char_rcvd = fgetc(GSM);
if(char_rcvd == 'C'){
sentence = 1;
output_b(0x04);
while(char_rcvd != '\n'){
inStr[i]= char_rcvd;
i++;
char_rcvd = fgetc(GSM);
}
}
//done = 4;
// output_b(done);
/*out_LCD(char_rcvd);
cursor_position(cursor);
cursor++;*/
//out_lcd_string(intt);
/*
output_b(char_rcvd); //shows the received character
delay_ms(50); //for troubleshooting purposes*/
}
/////////////////////////////////////////////////////////////////////////////
//
// usb_debug_task()
//
// When called periodically, displays debugging information over serial
// to display enumeration and connection states. Also lights LED1 based upon
// enumeration and status.
//
/////////////////////////////////////////////////////////////////////////////
void usb_debug_task(void) {
static int8 last_connected;
static int8 last_enumerated;
int8 new_connected;
int8 new_enumerated;
static int8 last_cdc;
int8 new_cdc;
new_connected=usb_attached();
new_enumerated=usb_enumerated();
new_cdc=usb_cdc_connected();
if (new_enumerated)
LED_ON(LED1);
else
LED_OFF(LED1);
if (new_cdc)
LED_ON(LED2);
else
LED_OFF(LED2);
if (usb_cdc_carrier.dte_present)
LED_ON(LED3);
else
LED_OFF(LED3);
if (new_connected && !last_connected)
printf("USB connected, waiting for enumaration...\r\n\n");
if (!new_connected && last_connected)
printf("USB disconnected, waiting for connection...\r\n\n");
if (new_enumerated && !last_enumerated)
printf("USB enumerated by PC/HOST\r\n\n");
if (!new_enumerated && last_enumerated)
printf("USB unenumerated by PC/HOST, waiting for enumeration...\r\n\n");
if (new_cdc && !last_cdc) {
printf("Serial program initiated on USB<->UART COM Port\r\n\n");
printf(usb_cdc_putc, "\r\n\nCCS CDC (Virtual RS232) Example\r\n\n");
}
last_connected=new_connected;
last_enumerated=new_enumerated;
last_cdc=new_cdc;
}
void main(void) {
char c;
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_low_volt_detect(FALSE);
setup_oscillator(False);
output_b(0x00);
output_low(PIN_C2);
delay_ms(500);
output_high(PIN_C2);
delay_ms(2000);
output_low(PIN_C2);
output_low(PIN_C2);
int_LCD();
//delay_ms(30000);
output_b(0x00);
LED_OFF(LED1);
LED_OFF(LED2);
LED_OFF(LED3);
printf("\r\n\nCCS CDC (Virtual RS232) Example\r\n");
#ifdef __PCH__
printf("PCH: v");
printf(__PCH__);
#else
printf("PCM: v");
printf(__PCM__);
#endif
printf("\r\n");
usb_init_cs();
#if !(__USB_PIC_PERIF__)
printf("USBN: 0x%X", usbn_get_version());
printf("\r\n\n");
#endif
while (TRUE) {
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
usb_task();
usb_debug_task();
if (kbhit()) {
c=getc();
if (c=='\n') {usb_cdc_putc('\r'); usb_cdc_putc('\n');}
if (c=='\r') {usb_cdc_putc('\r'); usb_cdc_putc('\n');}
else {usb_cdc_putc(c);}
}
if (usb_cdc_kbhit()) {
c=usb_cdc_getc();
if (c=='\n') {putc('\r'); putc('\n');}
if (c=='\r') {putc('\r'); putc('\n');}
else {putc(c);}
receive_text();
}
/*
i = 0;
while(inStr[i] != '\r'){
//usb_task();
usb_debug_task();
usb_cdc_putc(inStr[i]);
i++;
}*/
}
/*
output_b(0x00);
output_low(PIN_C2);
delay_ms(500);
output_high(PIN_C2);
delay_ms(2000);
output_low(PIN_C2);
output_low(PIN_C2);
int_LCD();
delay_ms(30000);
output_b(0x00);
receive_text();
i = 0;
while(inStr[i] != '\r'){
//usb_task();
usb_debug_task();
usb_cdc_putc(inStr[i]);
i++;
}
*/
}
void receive_text(void)
{
#use rs232(baud=4800,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, stream=GSM,ERRORS)
char ch;
int count=1;
int count2=10;
int count3=0;
//int i=0;
int b;
output_low(PIN_B7);
output_b(0xff);
fprintf(GSM, "AT+CMGF=1\r\n");
//fprintf(GSM, "\r\n");
delay_ms(3500);
//delay_ms(500);
fprintf(GSM, "AT+CMGR=3\r\n");
delay_ms(1);
enable_interrupts(int_rda);
//fprintf(GSM, "\r\n");
//delay_ms(750);
while(sentence != 1){
done= 0x08;
output_b(done);
}
//delay_ms(5000);
clear();
inStr[i]=0;
cursor_position(0x84);
out_lcd_string(inStr);
//program doesn't seem to be able to arrive at this point
done=3;
output_b(done);
// while(true){}
}
|
the purpose of this program is to read from my GSM and transfer it over to the pc through the USB.
my issue is that as soon as i try to interrupt the GSM (receive_text) the program freezes.
is it due to the fact that my GSM uses a different baudrate as well as the stream=GSM? |
|
|
Ttelmah Guest
|
|
Posted: Wed Jul 23, 2008 2:18 am |
|
|
Look at EX_SISR, for an example, of how to handle a serial interrupt.
The point is that when the interrupt happens, there is just _one_ character waiting for you. You need to read this, and get out of the ISR, ASAP. This is triply important when using USB, because the USB handler, _must_ reply to things from the PC, within quite a short time. If your code is sitting in another ISR, this won't happen, and the USB will go wrong.
As it is currently written, you read one character, and then if it is a 'C', you stay inside the ISR, and keep waiting for more characters, till a line-feed is seen. Given each character will take just over 2mSec to arrive, and a typical string may be several characters long, you are stuck inside the ISR. This is an absolute 'no-no', when running USB (and pretty much one the rest of the time...).
Either detect, and sort out the message in the main code, or use a 'state machine' in the ISR, resetting it when the 'C' is seen, and then advancing one state each time the ISR is called, and getting out of the ISR between states. A search here will find examples of both approaches.
Best Wishes |
|
|
madtoilet
Joined: 02 Apr 2008 Posts: 36
|
|
Posted: Wed Jul 23, 2008 9:36 am |
|
|
my serial interrupt is simlar to the example interrupt buffer. It's just a little bigger, i guess. Anyway, these interrupts have worked alone for separate programs for me but i can see what you're saying.
So i should interrupt one character at a time, yes? i'm actually receiving a gprmc message the 'c' is for a cms error that i know the gsm will give me for a certain reason.
So instead of staying in the ISR for so long, i'll just make the ISR read one character at a time, return to the main and repeat till it ends. Am i understanding you right? |
|
|
Ttelmah Guest
|
|
Posted: Thu Jul 24, 2008 2:23 am |
|
|
Your code, is _not_ "similar to the example interrupt buffer". If you look at this, you will see it only ever reads one character. This is a major, (and key) difference.
Just write the character to the buffer, and set a flag, when the line feed is seen.
Best Wishes |
|
|
madtoilet
Joined: 02 Apr 2008 Posts: 36
|
|
Posted: Thu Jul 24, 2008 12:12 pm |
|
|
i got it to interrupt properly. Thanks!
however, the code makes me do a keyboard hit before it will move the program forward.
this code seems to do it:
Code: |
if (kbhit()) {
c=getc();
if (c=='\n') {usb_cdc_putc('\r'); usb_cdc_putc('\n');}
if (c=='\r') {usb_cdc_putc('\r'); usb_cdc_putc('\n');}
else {usb_cdc_putc(c);}
}
if (usb_cdc_kbhit()) {
c=usb_cdc_getc();
if (c=='\n') {putc('\r'); putc('\n');}
if (c=='\r') {putc('\r'); putc('\n');}
else {putc(c);}
|
i tried to change this around but i only caused more problems.
Is there anyway to go around this?
and this part of the code is in a while(TRUE) loop |
|
|
|
|
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
|