CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

USB_serial confusion

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
madtoilet



Joined: 02 Apr 2008
Posts: 36

View user's profile Send private message

USB_serial confusion
PostPosted: Tue Jul 15, 2008 2:55 pm     Reply with quote

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 Smile
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 15, 2008 3:20 pm     Reply with quote

http://www.ccsinfo.com/forum/viewtopic.php?t=34264
http://www.ccsinfo.com/forum/viewtopic.php?t=31607
Ttelmah
Guest







PostPosted: Wed Jul 16, 2008 3:22 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jul 18, 2008 4:13 pm     Reply with quote

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







PostPosted: Sat Jul 19, 2008 4:19 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jul 22, 2008 10:24 am     Reply with quote

i think we got it to work. Windows is seeing the device now. thanks again guys Smile
madtoilet



Joined: 02 Apr 2008
Posts: 36

View user's profile Send private message

PostPosted: Tue Jul 22, 2008 4:13 pm     Reply with quote

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







PostPosted: Wed Jul 23, 2008 2:18 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jul 23, 2008 9:36 am     Reply with quote

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







PostPosted: Thu Jul 24, 2008 2:23 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jul 24, 2008 12:12 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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