View previous topic :: View next topic |
Author |
Message |
Martin Berriman
Joined: 08 Dec 2005 Posts: 66 Location: UK
|
I2C Force_HW not working |
Posted: Thu Feb 22, 2007 3:51 am |
|
|
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...
Edit: Forgot to say version 3.249 |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Feb 22, 2007 5:08 am |
|
|
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
|
|
Posted: Thu Feb 22, 2007 6:24 am |
|
|
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
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
|
|
Posted: Thu Feb 22, 2007 1:51 pm |
|
|
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
|
|
Posted: Thu Feb 22, 2007 2:35 pm |
|
|
Thank you PCM Programmer, that works now
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 .
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
Thanks again. |
|
|
Ttelmah Guest
|
|
Posted: Thu Feb 22, 2007 3:57 pm |
|
|
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
|
|
Posted: Fri Feb 23, 2007 2:37 am |
|
|
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
|
|
Posted: Fri Feb 23, 2007 2:51 am |
|
|
Thanks guys. I'm glad I was not being completely dim I'll certainly remember this nugget on info in future... |
|
|
|