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 CCS Technical Support

USB and I2C Wont work at that same time.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Dimlow
Guest







USB and I2C Wont work at that same time.
PostPosted: Thu Nov 22, 2007 3:03 am     Reply with quote

ok i have this simple code, its part of a larger project but i have stripped out almost all of it to show my point.

when i compile the code below with opt 9 the USB part works and im able to connect to the CDC com port, but the i2c does not work. With Proteus it tells me that the SDA timing is wrong. This all does the same thing in real hardware.

But....

If i compile the code with opt 11 the usb does not work (i cant connect to the cdc com port) and the I2C works fine! I found this when i added USB to a project that uses i2c for the lcd and the eeprom and a i2c keypad. when i added the usb all the i2c suff stopped working. i dont get it and it been giving me big problems.

im using pcwh 3.249 also tried it on the new v4 with the same results.

Code:

#include <18F4550.h>

#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOMCLR
#use delay(clock=48000000)
#use i2c(Master,Fast=400000, sda=PIN_E0, scl=PIN_E1,force_sw)


#include <usb_cdc.h>
void write_ext_eeprom(long int address, BYTE data)
{
   short int status;
   i2c_start();
   i2c_write(0xa0);
   i2c_write((address>>8)&0x1f);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
   delay_ms(10);
   i2c_start();
   status=i2c_write(0xa0);
   while(status==1)
   {
      i2c_start();
      status=i2c_write(0xa0);
   }
}

BYTE read_ext_eeprom(long int address) {
   BYTE data;
   i2c_start();
   i2c_write(0xa0);
   i2c_write((address>>8)&0x1f);
   i2c_write(address);
   i2c_start();
   i2c_write(0xa1);
   data=i2c_read(0);
   i2c_stop();
    return(data);
}
void Test_Failed()
{
}
   
void test_ext_eeprom()
{
   int16 x;
   int data;
   for(x=0;x<=8*1024;x++)
   {
      write_ext_eeprom(x,0xFF);
   }
   for(x=0;x<=8*1024;x++)
   {
      data=read_ext_eeprom(x);
      if(data!=0xFF) Test_Failed();

   }
}




void main()
{
   
   //usb_cdc_init();
      usb_init();
   delay_ms(10000);
   printf(usb_cdc_putc,"Hello World");
   test_ext_eeprom();
   while(1);
}


Any sugestions ?

Gary
Ttelmah
Guest







PostPosted: Thu Nov 22, 2007 3:38 am     Reply with quote

Try this trick:
Code:

#use delay(clock=48000000)
#use i2c(Master,Fast=400000, sda=PIN_E0, scl=PIN_E1,force_sw)
#include <usb_cdc.h>

#use delay(clock=48000000)

The USB code, does use the delay_us pause in a couple of places. I'd suspect that what is happening, is that interrupts, are being disabled in delays, because of this.
Now, you have a huge number of quite long delays (why not poll the chip, rather than delaying for 10mSec after the write - this is how the CCS I2C EEPROM code does it). USB, has a requirement in a few places, that transactions are handled inside a limited time - I think it is 10mSec, but I'd have to go and re-read the USB paperwork to be sure. If interrupts are being disabled in the delays, with your huge number of delays, and especially the long one, it is not suprising that USB fails.
Adding the second delay definition, means that separate code is generated for the delays in the 'main' code, and the delays in the USB, which should stop interrupts from being disabled in these, if this is the problem.

Best Wishes
Dimlow
Guest







PostPosted: Thu Nov 22, 2007 4:04 am     Reply with quote

Oops, yes that delay was put in there while seeing if i could slow things down a little as the problem with the i2c seem to be that is was running to fast. but anyway as you can see, i do poll the eeprom after the write to see when its complete. The problem in not just the eeprom, its all I2C. Still, i tried your sugestion and it still has the same problems. I can't think why the usb would work with #opt 9 and not with #opt 11 ? All my i2c stuff , and there is a lot of it, because the board has LCD,KEYPAD and EEPROM I2C has all been tested and has been working fine. A Simple test with USB only on the board works fine. I2C Only, also works fine. Put them together. BAM! Problems.

Oh yes tested the extra delay(clock=48000000), still no joy, same problem
Dimlow
Guest







PostPosted: Thu Nov 22, 2007 4:24 am     Reply with quote

Just to make it clear, even with the Deleay_ms(10); removed from the code i still have the problem.

thanks for all your help Ttelmah!

Regards
Gary
Ttelmah
Guest







PostPosted: Thu Nov 22, 2007 5:16 am     Reply with quote

You say in your original post, that you have tested with 'real hardware', have you tried the possible fix with this?.
Proteus, has problems with I2C, often spuriously reporting problems, so I'd not trust this.
One obvious comment. Why can't you use the hardware I2C?. It really is massively 'better'. Even if it means you have to reroute a couple of bits it'd be worth it.
Which version of V4, are you trying?. There were some reported bugs with the higher optimisation levels when they were introduced (I must admit, I thought most were fixed by 3.249), and the early V4 compilers, are awful.
One more comment. You are writing to one more location, and reading from one more location, than the EEPROM 'has'. You need to stop when the count equals 8*1024, not include this value.

Best Wishes
Dimlow
Guest







PostPosted: Thu Nov 22, 2007 6:41 am     Reply with quote

The eeprom test above is just to show the problem. knocked it up quick to test in small program. problem with hardware i2c is that the board is already manufactured and I'm stuck with the pins to use. yes have tested with real hardware and when using usb. i2c does not work. i2c works fine without usb. all the lcd, etc works great.

I realize that proteus does have problems. But it is reacting the same way as the board.

I'm not in the office right now, I will do more testing when I get back.

this has been troubling me now for a week, time is getting short. I may have to find another way for comms to pc. maybe make a custom cable and use rs232 through the usb socket on the board.

BTW the board is a small cnc pcb drilling machine controller and was designed to receive is drilling positions via usb. it was tested with usb and i2c before manufacter and they worked . but they were never test whilst using both i2c and usb at the same time!

oh poo !

Gary
Dimlow
Guest







PostPosted: Fri Nov 23, 2007 9:29 am     Reply with quote

Right, I have struggled with this for long enough, before i go and write my own I2C Master code to replace the CCS built in functions.

Has anyone already done this and is willing to share the code ?

Gary
Ttelmah
Guest







PostPosted: Fri Nov 23, 2007 10:16 am     Reply with quote

Try something really silly:
Code:

BYTE read_ext_eeprom(long int address) {
   BYTE data;
   i2c_start();
   i2c_write(0xa0);
   i2c_write((address>>8)&0x1f);
   i2c_write(address);
   i2c_stop();
   i2c_start();
   i2c_write(0xa1);
   data=i2c_read(0);
   i2c_stop();
   return(data);
}

This is technically, completely 'wrong', but it fixed a problem a good friend was having with the I2C.
There was a thread about this some time ago.
It appeared that there was a problem with handling repeated 'start' commands (which is meant to be legitimate I2C), in some circumstances.

Best Wishes
Guest








PostPosted: Fri Nov 23, 2007 2:18 pm     Reply with quote

I have been searching through all the posts on i2c and cant find anything that's relevant to this.

Also i think it has something to do more with the optimizations than it does with the i2c.
Ah yes, your code. Its not just related to eeprom i also use io expander's and they stop working too, so its all i2c. I believe its down to timing issues when in the different optimizations. The clue was that both usb and i2c do work, but one works with #opt 9 and the the other with #opt 11.

#opt 9 usb works fine, i2c does not
#opt 11 usb does not work but i2c does

i have no idea why this is, I'm just about to test the timing on the scope to see what is really going on with the i2c in #opt 9. will get back with results. I was just about to start coding bit bang i2c routines when i saw you post. but will leave that till later.

lets warm up the scope..

Regards
Gary
Dimow
Guest







PostPosted: Fri Nov 23, 2007 2:25 pm     Reply with quote

Just wanted to add that if i compile just i2c code ie comment out #include <usb_cdc.h> and all other usb stuff, i2c works fine with #opt 9.

Very Strange

Gary
Guest








PostPosted: Fri Nov 23, 2007 2:46 pm     Reply with quote

Bugger! Sorry Guys!

I don't quite know how to say this and i don't know why i did not do it before but a soon as i attached the scope to the board all the i2c started working. In now kicking myself in the teeth, I think i have a bad board.

anyway the good news it when i set i2c to 100k i get 100k on the scope
but with 400k i get 375k on the scope, but it still works.

remove the scope leads and no i2c.
Well we live and learn
Regards

Gary
Guest








PostPosted: Fri Nov 23, 2007 3:03 pm     Reply with quote

And another thing, usb still dont work with #opt 11 but i can live with that.

Gary
Ttelmah
Guest







PostPosted: Fri Nov 23, 2007 3:58 pm     Reply with quote

If you search here, you will find why you won't get 400K, with software I2C. Basically, the processor can't shift the data out of the byte, and handle the timings 'right', at this rate in software.
The scope will be slightly slowing the edges. Remember that software I2C, (and the hardware I2C, on most chips), won't have the _required_ edge timing controls for the higher rates (400K, requires slope control on the falling edge to be 'in spec'). It sounds as if at least one of your devices is fussy.
Raises the question also, of what pull-up resistances you are using, and whether you have any series resistances in the I2C lines as well (some device inputs, require these to prevent spikes and fast edges, from causing problems...).

Best Wishes
Dimlow
Guest







PostPosted: Fri Nov 23, 2007 5:21 pm     Reply with quote

Its very strange that it only shows its head when the usb is active, the usb traces on the board are routed far away from any on the i2c lines.

on the scope the rising edge was 270ns with 4.7 k resistors, but i have now changed them to 2.6 k and the edge is now down to 96ns. The signal look nice and clean, no noise.

the board uses two pcf 8574 io expander's and two 2464 eeproms there are no series resistors used.

And another thing i have just realized whilst typing this, the board originally was going to a single PCF8575 16 bit io expander, but was swapped for two PCF8574. I have just realised that the 8574 are 100k devices and not 400k as the 8575's are, i have been running them at 400k no wonder i have problems.

Its been a bad week, maybe i should get more sleep.

Gary
Ttelmah
Guest







PostPosted: Sat Nov 24, 2007 3:29 am     Reply with quote

I think 'Aargh', applies....
Most people here, have had days/weeks like this, but at least it is explained.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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