|
|
View previous topic :: View next topic |
Author |
Message |
HTAluvBeBeo
Joined: 23 Feb 2008 Posts: 35
|
use #INT_USB with usb_cdc |
Posted: Sat Jul 05, 2008 3:04 am |
|
|
Hello friends
When I used usb_cdc.h for a virtual com, I can not use #INT_USB because this interrupt is used before.
My project is a char LCD driven by LCD smartie software via USB
I did a serial version. It works fine.
My method is using interrupt to wait for data come and add to an array, then main program will read data from this array.
But with USB, I can not use #INT_USB to collect data when they come.
How can I do now
I am trying to use software interrupt by using timer0 to check usb_cdc_kbhit()
sory for my English:D |
|
|
Ttelmah Guest
|
|
Posted: Sat Jul 05, 2008 3:25 am |
|
|
The USB code, has to do a lot more than just handle data arriving. The interrupt fires all the time, for transactions on other endpoints, so wouldn't be much use for your application.
Edit the CCS cdc code, and in the routine 'usb_isr_tok_out_cdc_data_dne' (which is the code that is actually called when a character _does_ arrive), and at the end of this routine, call your routine.
Make it short though, since this is inside the ISR, and USB adds tighter requirements on the ISR handling than normally apply (some transactions _must_ be handled in only a very few mSec, for USB to keep working OK).
Best Wishes |
|
|
HTAluvBeBeo
Joined: 23 Feb 2008 Posts: 35
|
|
Posted: Sat Jul 05, 2008 4:28 am |
|
|
thank you for replying:D
With my mehod, using timer to check usb_cdc_kbhit() very ??us
The my usb_lcd works but it seemed that the transfer speed is low, so bargraph is display slower than it would be
Then I tried to edit usb_cdc.h but it does not work :( unlucky me
Code: | //handle OUT token done interrupt on endpoint 3 [buffer incoming received chars]
void usb_isr_tok_out_cdc_data_dne(void) {
usb_cdc_get_buffer_status.got=TRUE;
usb_cdc_get_buffer_status.index=0;
#if (defined(__PIC__))
#if __PIC__
usb_cdc_get_buffer_status.len=usb_rx_packet_size(USB_CDC_DATA_OUT_ENDPOINT);
#else
usb_cdc_get_buffer_status.len=usb_get_packet_buffer(
USB_CDC_DATA_OUT_ENDPOINT,&usb_cdc_get_buffer_status_buffer[0],USB_CDC_DATA_OUT_SIZE);
#endif
#else
usb_cdc_get_buffer_status.len=usb_get_packet_buffer(
USB_CDC_DATA_OUT_ENDPOINT,&usb_cdc_get_buffer_status_buffer[0],USB_CDC_DATA_OUT_SIZE);
#endif
/////////////////my modify////////////////////////////////////////////////////////////////////////////////
//if(usb_cdc_kbhit())
// {
buffer[buff_in] = usb_cdc_getc();
if (++buff_in > buff_size - 1)
{
buff_in = 0;
}
// }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
} |
is it right??
and here is my main
Code: | #include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <lcd_4bit.c>
#define preload_2 200
#define preload_3 230
#define pwm pin_b3
#define buff_size 32
#define GPO1 pin_A1
int pwm_duty;
int pwm_count;
char buffer[buff_size];
char buff_in;
char buff_out;
#include <usb_cdc.h>
byte rs232_getch(void); //gets byte from serial receive buffer
void rs232lcd(byte); //sends rs232 received data to LCD or translates if needed
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_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()
{
setup_adc(adc_off);
setup_adc_ports(NO_ANALOGS);
set_tris_a(0x00);
set_tris_b(0x00);
output_a(0x00);
output_b(0x00);
pwm_duty = 255;
buff_in = 0;
buff_out = 0;
output_high(PIN_B3);
delay_ms(200);
lcd_init();
delay_ms(200);
usb_init();
delay_ms(100);
while(1)
{
usb_task();
usb_debug_task();
if (buff_in != buff_out) //if buffer NOT empty
{
rs232lcd(rs232_getch()); //process bytes
}
}
}
|
|
|
|
HTAluvBeBeo
Joined: 23 Feb 2008 Posts: 35
|
|
Posted: Sat Jul 05, 2008 6:50 am |
|
|
I've just do some test
The problem probably is usb_isr_tok_out_cdc_data_dne() rountine is called only one time when I send a string like "ccsforum", for instance
So, with usb_cdc_getc(); I only catch "c" from string "ccsforum"
How can I fix with this:-?
Or is there any way else can I do to handle with arrivng data
Thank you, friends |
|
|
Ttelmah Guest
|
|
Posted: Sat Jul 05, 2008 10:07 am |
|
|
Of course it is only called once. There is a _block_ of data received. The ISR itself is also only called once in this condition. You need to either use the usb kbhit code, and keep getting characters till it goes false, or do this yourself. Look at the usb_cdc_getc code, to see how it increments the buffer status 'index', and compares this to 'len', then clearing the 'got' flag when the length is reached.
You have to get away from thinking like RS232. Though USB, is a serial interface, the transfers along this are done in hardware, and you will receive a block of data, which if it was sent because there was a timeout (more characters did not arrive), could contain as few as one character, but will normally contain more. Usually up to eight characters. The interrupt will be called for transmit transfers, receive transfers, and control transfers, all of which have to be identified, and separated to call their required code. This routine, is called for the equivalent of the RS232 receive transfer, but think of the 'UART' as having a much larger hardware buffer than the CCS one, so the transfer may have several characters arriving. There is no 'per character' interrupt ability for USB.
Personally, I'd just be running your 'main' code, based on a state machine, and check the USB kbhit status in the loop for this.
Best Wishes |
|
|
HTAluvBeBeo
Joined: 23 Feb 2008 Posts: 35
|
|
Posted: Sat Jul 05, 2008 11:25 am |
|
|
thank you so much
I undrstood
As you can see, I do not know much about USB:D
So it is very simple
Code: | /////////////////my modify////////////////////////////////////////////////////////////////////////////////
while(usb_cdc_kbhit())
{
// printf("1"); // for debug but it caused bug :))
buffer[buff_in] = usb_cdc_getc();
if (++buff_in > buff_size - 1)
{
buff_in = 0;
}
}
|
It works fine now
Thank you again |
|
|
|
|
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
|