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

I2C Force_HW not working

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



Joined: 08 Dec 2005
Posts: 66
Location: UK

View user's profile Send private message

I2C Force_HW not working
PostPosted: Thu Feb 22, 2007 3:51 am     Reply with quote

I must be doing something stupid but I cannot seem to get FORCE_HW working.

I am using a PIC with built in MSSP that can operate as I2C master which is what I want (PIC 18F4620).

If I leave out FORCE_HW and let CCS generate SW I2C handler then everything works fine but I could do with reducing the code footprint a bit so changing to HW I2C will save me a few percent. Since it works in SW mode, I am sure I am setting the tristate directions correctly (I'm using FAST_IO) and addressing the varoius I2C devices correctly. I must not be configuring something that I should be but can't seem to see where.

I have tried using setup_spi(SPI_SS_DISABLED) in case it was trying to use the MSSP for SPI but no luck. My program gets stuck at the first I2C_start command waiting for the hardware to say that it has started successfully.

The CCS help file has not shed any light and searching on the forum here for FORCE_HW issues only seems to highlight problems where the PIC being used in not able to act as I2C master (ie no MSSP).

Any thoughts appreciated... Confused
Edit: Forgot to say version 3.249
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Feb 22, 2007 5:08 am     Reply with quote

You don't show your #use I2C line, so we don't have enough information to go on.
Or, as always: post a small, complete, compilable example program. Should not be more than 10 lines.

Using setup_spi(SPI_SS_DISABLED) is dangerous as this is an invalid combination of parameters. The official call for disabling SPI is setup_spi(FALSE). I didn't check it, but the sequence for disabling SPI and enabling I2C most likely have some dependencies as they are basically the same hardware unit. I would just leave out the call to setup_spi() at all.
Martin Berriman



Joined: 08 Dec 2005
Posts: 66
Location: UK

View user's profile Send private message

PostPosted: Thu Feb 22, 2007 6:24 am     Reply with quote

Ok, here's some simple code. Unless the #use I2C takes care of it, I am obviously missing something to configure the MSSP as I2C... There does not seem to be a setup_i2c function like there is a setup_spi one Confused
The program gets stuck in i2c_write (rather than i2c_start as I said earlier).

Code:
#include <18F4620.h>

#FUSES NOWDT
#FUSES HS
#FUSES NOCPD
#FUSES NOPROTECT
#FUSES MCLR
#FUSES PUT
#FUSES NOBROWNOUT
#FUSES NOLVP

#use delay(clock=20000000)
#use i2c(MASTER, scl=PIN_C3, sda=PIN_C4, SLOW=100000, FORCE_HW)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)

void main(void)
{
   set_tris_a(0b11111111);
   set_tris_b(0b11101101);
   set_tris_c(0b10000000);
   set_tris_d(0b00000000);
   set_tris_e(0b11111111);

   while (true)
   {
      i2c_start();
      delay_ms(1);
      i2c_write(0xAC);
      delay_ms(1);
      i2c_stop();
      delay_ms(1);
   }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 22, 2007 1:51 pm     Reply with quote

When you invoke the hardware i2c library, the compiler inserts start-up
code that configures Pins C3 and C4 as inputs. See the lines shown in
bold below. You're overriding this with your set_tris_c(0x80) statement.
Quote:

.................... void main(void)
.................... {
00048: CLRF TBLPTRU
0004A: BCF RCON.IPEN
0004C: CLRF FSR0H
0004E: CLRF FSR0L
00050: BSF TRISC.3
00052: BSF TRISC.4

00054: MOVLW 31
00056: MOVWF SSPADD
00058: MOVLW 28
0005A: MOVWF SSPCON1
0005C: BSF SSPSTAT.SMP
0005E: BCF SSPSTAT.CKE
00060: MOVF ADCON1,W
00062: ANDLW C0
00064: IORLW 0F
00066: MOVWF ADCON1
00068: MOVLW 07
0006A: MOVWF CMCON

I compiled this with PCH vs. 4.025.
Martin Berriman



Joined: 08 Dec 2005
Posts: 66
Location: UK

View user's profile Send private message

PostPosted: Thu Feb 22, 2007 2:35 pm     Reply with quote

Thank you PCM Programmer, that works now Very Happy

I thought that because I was using FAST_IO, I was responsible for setting the pins as inputs or outputs (indeed without FORCE_HW, I am responsible) but it seems that when using FORCE_HW the hardware takes full responsibility for setting those pin directions - so I get the day off Wink .

Having now removed from my code the lines to change the SDA pin direction when reading and writing, and also set both SDA and SCL pins to inputs in the TRIS settings, FORCE_HW works as it should and saves me 3% code space as well.

A note in the CCS help file under FORCE_HW would have saved a lot of trouble here Rolling Eyes

Thanks again.
Ttelmah
Guest







PostPosted: Thu Feb 22, 2007 3:57 pm     Reply with quote

Er. This is not a CCS problem.
It is rather bad 'data sheeting' on the chip itself. Microchip, say that the hardware peripheral 'overrides' the I/O pins, and that it is the users responsibility to set the TRIS bits, then gives what to set them for for the slave modes, but not for the master mode. In fact it is only because on a lot of other chips, they give the override circuit, where it is shown that for this section, the pins must be set as inputs, or the output driver will block data reception, that 'older users', will know to try setting the pins as inputs.
If you use 'fast_io', it is up to you to control the TRIS. The initialisation code, is 'residual', CCS, automatically insert it if you have the #use I2C line, whatever I/O mode you specify. If you leave the port in the CCS default 'standard_io' mode, it'll work without you changing anything.

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Feb 23, 2007 2:37 am     Reply with quote

Ttelmah wrote:
Er. This is not a CCS problem.
It is rather bad 'data sheeting' on the chip itself. Microchip, say that the hardware peripheral 'overrides' the I/O pins, and that it is the users responsibility to set the TRIS bits, then gives what to set them for for the slave modes, but not for the master mode.
Thanks for this clarification, I did look into the datasheet for this information and it got me too.

In chapter 17.4 on I2C mode the datasheet says
Quote:
The user must configure these pins as inputs or outputs through the TRISC<4:3> bits.
No other information is given on the required settings for each pin. This is very confusing because here Microchip suggests at least one of the pins should be configured as an output.

Only after your extra information and reading again I found the following information hidden in the chapter on I2C Operation
Quote:
Selection of any I2C mode with the SSPEN bit set
forces the SCL and SDA pins to be open-drain, provided
these pins are programmed to inputs by setting
the appropriate TRISC bits.
Martin Berriman



Joined: 08 Dec 2005
Posts: 66
Location: UK

View user's profile Send private message

PostPosted: Fri Feb 23, 2007 2:51 am     Reply with quote

Thanks guys. I'm glad I was not being completely dim Laughing I'll certainly remember this nugget on info in future...
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