|
|
View previous topic :: View next topic |
Author |
Message |
magestik
Joined: 16 Oct 2008 Posts: 59
|
USB on PIC18F4550 |
Posted: Mon Feb 23, 2009 3:33 am |
|
|
Hello,
I have a problem sending character via a virtual keyboard, using a PIC18F4550.
another PIC is making a printf in an infinite loop. This PIC has a fgetc to retrieve the characters sent.
The idea is to retrieve the character with fgetc, then send it via a virtual keyboard to the computer.
But it seems that the programm does not retrieve all data, or does not send all data via USB. Do i need to stop or pause the USB line while i use fgetc ? if so, i don't know how.
Or is there another problem i didn't notice ?
Here is the complete code, thank you for your help.
Code: | #include <18F4550.h>
#fuses HS,WDT,NOPROTECT,NOLVP,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=20000000) // 48000000
#use rs232(baud=3600,xmit=PIN_D2,rcv=PIN_D3,bits=8, STOP=2, stream=toto)
//Tells the CCS PIC USB firmware to include HID handling code.
#define USB_HID_DEVICE TRUE
//the following defines needed for the CCS USB PIC driver to enable the TX endpoint 1
#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1 for IN bulk/interrupt transfers
#define USB_EP1_TX_SIZE 8
#define USB_EP2_TX_ENABLE USB_ENABLE_INTERRUPT //turn on EP2 for IN bulk/interrupt transfers
#define USB_EP2_TX_SIZE 8
#define USB_EP2_RX_ENABLE USB_ENABLE_INTERRUPT //turn on EP2 for IN bulk/interrupt transfers
#define USB_EP2_RX_SIZE 4
#define LED1 PIN_A5
#include <pic18_usb.h>
#include <usb_desc_kbmouse.h> //USB Configuration and Device descriptors for this UBS device
#include <usb.c> //handles usb setup tokens and get descriptor reports
#include <string.h>
int8 i=4;
int8 unbyte=0x0b;
int8 send_byte;
int8 trame_kb[16];
int8 tab[64];
void main(void)
{
static int8 tx_msg[7]={0,0,0,0,0,0,0}; // 8 bytes array
int8 led_count;
delay_ms(10);
usb_init_cs();
delay_ms(1);
while(1)
{
usb_task();
led_count++;
if(led_count > 60)
{
led_count=0;
output_toggle(LED1);
}
if(kbhit(toto))
{
unbyte = fgetc(toto);
if(unbyte=='a') tx_msg[2] = 0x04;
else if(unbyte=='b') tx_msg[2] = 0x05;
else if(unbyte=='c') tx_msg[2] = 0x06;
else if(unbyte=='d') tx_msg[2] = 0x07;
else if(unbyte=='e') tx_msg[2] = 0x08;
else if(unbyte=='f') tx_msg[2] = 0x09;
else tx_msg[2] = 0x0a; // g
}
if(usb_enumerated())
{
usb_put_packet(2,tx_msg,sizeof(tx_msg),USB_DTS_TOGGLE);
tx_msg[2]=0;
usb_put_packet(2,tx_msg,sizeof(tx_msg),USB_DTS_TOGGLE);
delay_ms(1);
}
}
} |
|
|
|
Ttelmah Guest
|
|
Posted: Mon Feb 23, 2009 3:59 am |
|
|
To do this, you _must_ receive the serial data on the hardware serial port. 'Software serial', which is what you are using, can _only_ work, if the processor is basically doing nothing else during the character transfer. USB, _requires_ that the slave processor responds to things occuring on the bus, so you can't "stop or pause the USB line". With a lot of care, it _might_ just be possible to get this to work, by disabling interrupts for the one character, but it is unlikely to be reliable, since the duration of some USB interrupts will make it likely that you will mitime the start bit detection anyway...
Since you are talking to another PIC, why on earth use such an 'odd' serial setup. 3600bps?. Two stop bits?.
Best Wishes |
|
|
magestik
Joined: 16 Oct 2008 Posts: 59
|
|
Posted: Mon Feb 23, 2009 4:01 am |
|
|
Ttelmah wrote: | Since you are talking to another PIC, why on earth use such an 'odd' serial setup. 3600bps?. Two stop bits?. |
I'm using another pic for debug, when it will work, the rx line will be connected to a RF receiver, which works @ 3600bps, 2 stop bits.
I'll try the hardware rx/tx right away. |
|
|
magestik
Joined: 16 Oct 2008 Posts: 59
|
|
Posted: Mon Feb 23, 2009 5:21 am |
|
|
I changed to hardware pins, i can now receive and send characters. But for exemple if i receive the character 'a', it will send 'a' as long as it does not receive another character, what's wrong with that ?
Another thing, does it mean i can't use USB + RS232 hardware + RS232 software with the 18F4550 ? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Mon Feb 23, 2009 5:27 am |
|
|
In HID, cause it's continuously sending, you have to place an idle message, to stop sending the character message.
Code: | if (kbhit(toto))
{
}
else
tx_msg[2] = 0; |
|
|
|
magestik
Joined: 16 Oct 2008 Posts: 59
|
|
Posted: Mon Feb 23, 2009 9:33 am |
|
|
Using the else condition, the program does not work . |
|
|
magestik
Joined: 16 Oct 2008 Posts: 59
|
|
Posted: Tue Feb 24, 2009 2:56 am |
|
|
Now that USB + hardware RS232 works, could i use usb_detach() and usb_attach() to disable and enable USB while i use software RS232 ??
Knowing that i only use the USB line to send data, i don't need to receive anything.
I absolutely need the SW RS232 combined with the HW RS232, and the USB line . |
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 24, 2009 3:26 am |
|
|
At what baud rate?.
You _may_ be able to get the software RS232 to work, by disabling interrupts on a per character basis. I have in the past posted 'wrapper' functions to do this. A search should find them. However I'd say that the chances of repeatably reliable software _reception_, in this environment, are relatively poor, since if your code is doing much else, guaranteeing when you are going to arrive at the character handler at the required time, will become hard. Try, using the INT0 line for your software receive, and again a search here will find examples of how to do this.
However, there is no 'absolutely need' about it. I2C UART chips are readily available, and 'solve' this problem...
Best Wishes |
|
|
magestik
Joined: 16 Oct 2008 Posts: 59
|
|
Posted: Tue Feb 24, 2009 3:56 am |
|
|
Baud rates would be :
HW RS232 : 9600
SW RS232 : 3600 |
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 24, 2009 4:14 am |
|
|
Other questions. What are the 'nature' of the serials?. Half duplex, full duplex, what triggers the data, how much is likely to transfer at a time?.
Best Wishes |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Feb 24, 2009 4:14 am |
|
|
I wonder, if standard software RS232 will work while USB is activated, because of the required USB interrupt activity. I'm using 1200 baud software RS232 TX with USB, but based on timer interrupts. |
|
|
magestik
Joined: 16 Oct 2008 Posts: 59
|
|
Posted: Tue Feb 24, 2009 4:59 am |
|
|
Ttelmah wrote: | What are the 'nature' of the serials?. Half duplex, full duplex, what triggers the data, how much is likely to transfer at a time?. |
This will be half duplex.
On the HW RS232, i send a read command, then get the data.
On the SW RS232, i need to watch if a command is coming, then send data if i read the command. If no command, i keep watching.
How much to transfer at a time ? hopefully the maximum, i don't know. If i can make the whole thing work, it will be a start .
For now, SW doesn't work. |
|
|
magestik
Joined: 16 Oct 2008 Posts: 59
|
|
Posted: Tue Feb 24, 2009 10:59 am |
|
|
Now i have a new problem .
I will use only the HW RS232 :
I'm sending a command to a module (this part seems to work), and the module send me back 10 bytes of data.
So i need to get them using getc(). I need to get the 10 bytes, and send just the 3rd byte.
Code: | while(1)
{
usb_task();
led_count++;
if(led_count > 60)
{
led_count=0;
output_toggle(LED1);
}
delay_ms(10); // 5 ms minimum
if(input(VNC1L_RTS)==0)
fprintf(VNC1L, "DRD%c", 13); // Sending the read command
for(i=0; i<10; i++) // getting 10 bytes
{
unbyte = fgetc(VNC1L);
if(i==2) tx_msg[2]=unbyte;
}
if(usb_enumerated())
usb_put_packet(2,tx_msg,sizeof(tx_msg),USB_DTS_TOGGLE); // sending 1 byte
delay_ms(5);
} |
The program seems to stop in the for condition. My (obvious?) problem is having the for condition with USB in the same program.
I need to get the 10 bytes.
This chip is driving me crazy.
Any idea will be greatly appreciated |
|
|
magestik
Joined: 16 Oct 2008 Posts: 59
|
|
Posted: Mon Mar 02, 2009 12:39 pm |
|
|
Hello,
Still fighting the PIC18F4550, i gave up with the HW & SW uart . This simply does not want to work.
Weird thing, i can bit bang the RX line.
If i do :
Code: | for(i=0; i<200; i++) // getting 10 bytes + start/2stop
{
tab[i] = input(PIN_C7);
delay_us(104);
} |
Since the other module send data @9600bps, that makes 104µs for one bit.
If i resume :
- HW does not work (getc, fgetc, kbhit) with USB
- SW does not work with USB
- Bit banging on RX line works, BUT, i am sometimes missing a few bit, which is unacceptable .
The weirdest thing is that "kbhit()" does not react, but when bit banging, i can see all the data coming.
Is there a more reliable way of bit banging uart ? (which i am sure there is, as i am a newbie with pics ).
Thanks . |
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 02, 2009 1:32 pm |
|
|
The hardware UART should work fine with USB. getc etc., will all work.
The software UART will fail, for exactly the same reason as the bit banging. Every time the USB interrupts, the 104uSec delay, will go 'long' by many dozen uSec, while the interrupt is handled. This will kill software comms.
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
|