 |
 |
| View previous topic :: View next topic |
| Author |
Message |
devau
Joined: 30 Jan 2007 Posts: 9 Location: Switzerland
|
|
Posted: Mon Sep 21, 2026 7:58 am |
|
|
I have changed now the address in the code from 0x4E to 0x9C
(On the LCD's PCF8574?: This can't be done, as there's only jumpers for the A0,A1,A2 bits.)
This is what I used:
//#pin_select SDA1=PIN_B2 leave commented out, else compiler says*** Error 7, Invalid Pre-Processor directive Pin already used
//#pin_select SCL1=PIN_B1 leave commented out, else compiler says*** Error 7, Invalid Pre-Processor directive Pin already used
#pin_select SDA1IN=PIN_B2
#pin_select SDA1OUT=PIN_B2
#pin_select SCL1IN=PIN_B1
#pin_select SCL1OUT=PIN_B1
#use i2c(Master,I2C1,fast=100000,sda=PIN_B2,scl=PIN_B1,force_hw,STREAM=LCD)
set_open_drain_b(0B00000110); // B1 B2
set_tris_B(0B00000000);
Processor hangs after this line:
i2c_transfer_out(LCD, (uint8_t) LCD_ADDRESS, buffer, 1); |
|
 |
devau
Joined: 30 Jan 2007 Posts: 9 Location: Switzerland
|
|
Posted: Mon Sep 21, 2026 8:17 am |
|
|
"The PIC18F27Q43 no longer uses the old MSSP module; instead, it features a completely redesigned, dedicated I2C hardware module. Regarding addressing, this module strictly adheres to the 7-bit format. Here is the precise breakdown of how your address is composed and why 0x9C would be incorrect: 1. The mathematical misunderstanding regarding 0x9C. If you have a generic LCD board based on the PCF8574 (TI style), the 7-bit base address is 0x27. If you shift 0x27 left by one bit (0x27 << 1), you get 0x4E (or 0x4F for a read operation). Where does the value 0x9C come from? That would be the result of shifting 0x4E to the left (0x4E << 1 = 0x9C). In this case, a double shift has occurred, rendering the address completely unusable on the bus."
Anyway: Wrong addresses should never make the PIC hanging. I think the error lies in the CCS Compiler itself (used version is 5.119). As I said: I gave up. Using software method:
#use i2c(Master, Fast, sda=PIN_B2, scl=PIN_B1, STREAM=LCD)
works flawlessly :-) |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 20145
|
|
Posted: Mon Sep 21, 2026 9:51 am |
|
|
OK.
The point was you said that it wanted address 4E from its data sheet. It sounds as if you have already shifted this from the TI address?.
However 4E suggests this is a unit using the TI I/O expander?.
If so, the first thing is to get rid of the pin definitions in your
#USE I2C:
| Code: |
#pin_select SDA1IN=PIN_B2
#pin_select SDA1OUT=PIN_B2
#pin_select SCL1IN=PIN_B1
#pin_select SCL1OUT=PIN_B1
#use i2c(Master,I2C1,fast=100000,STREAM=LCD)
//Then your transfer
i2c_transfer_out(LCD, LCD_ADDRESS, &buffer, 1);
|
You are handing 'buffer' to this call, but you need to pass the _address_
of buffer. As called you will be writing data into a random location in
memory, which will cause either data corruption, locking or crashing. |
|
 |
devau
Joined: 30 Jan 2007 Posts: 9 Location: Switzerland
|
|
Posted: Mon Sep 21, 2026 10:35 am |
|
|
in your #iuse... line the keyword "force_hw" is missing. Without it, CCS assumes software mode.
I compiled it now with "force_hw". And to be sure, I used:
uint8_t buffer = 0x00;
And still the PIC hangs at the i2c_transfer call. |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 20145
|
|
Posted: Mon Sep 21, 2026 12:43 pm |
|
|
No. If you use the hardware port name (I2C1), this automatically forces
the use hardware selection.
The only reason that will hang, is if is is not getting an ACK from the attached
device. |
|
 |
devau
Joined: 30 Jan 2007 Posts: 9 Location: Switzerland
|
|
Posted: Tue Sep 22, 2026 3:10 am |
|
|
| Ttelmah wrote: |
The only reason that will hang, is if is is not getting an ACK from the attached
device. |
As I said, without hardware mode it works - means that ACK works.
To me, it looks like CCS isn't implementing this properly. One could try setting it up from scratch, including all the relevant registers. It would likely work then, proving that CCS is doing something wrong. Unfortunately, I don't have the time for that, so I'm sticking with the software solution. However, if anyone does have the time, I’d be happy to test it using any code provided. |
|
 |
Woody
Joined: 11 Sep 2003 Posts: 92 Location: Warmenhuizen - NL
|
|
Posted: Wed Sep 23, 2026 2:34 am |
|
|
The CCS compiler might not be without its flaws but so far most problems I ran into were due to a lack of understanding on my part :-)
Your compiler version is way newer than the one I used in my example above here, and my code runs without problems for years now. Never 'hangs' the CPU.
What I see as strange in your code is in your
| Code: | | #use i2c(Master,I2C1,fast=100000,sda=PIN_B2,scl=PIN_B1,force_hw,STREAM=LCD) |
line. AFAIK when you use I2C1 in that line, you should not use the sda=pin and scl=pin statements and vice versa. These are implicitly made and the #pin_select statements make the hardware connection for you. By using the default ports here (look up PPS in the DS) you can control slew rate etc. Also the force_hw statement is unnecessary; I2C1 _is_ the hardware module.
But hey, if the sw solution works for you, leave it at that. I2C can be a real hassle to get to work but I think you should be able to get this running using the hardware module. |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 20145
|
|
Posted: Thu Sep 24, 2026 12:01 pm |
|
|
I did try using the I2C peripheral on a Q43, talking to a EEPROM, and it merrily
worked OK with the current function.
However it is well worth saying that the software I2C for the master is
often more reliable, and just as fast on many modern chips. The nice
thing is the functions are more forgiving than the peripheral is..... |
|
 |
asmallri
Joined: 12 Aug 2004 Posts: 1678 Location: Perth, Australia
|
|
Posted: Fri Sep 25, 2026 7:34 pm |
|
|
| Ttelmah wrote: | | The nice thing is the functions are more forgiving than the peripheral is..... |
This is true however in most cases what it is really masking is a flaw in the hardware implementation i.e pcb layout, incorrrect termination of the I2C bus, emi issues, insuffieicent power supply filtering etc. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 20145
|
|
Posted: Sat Sep 26, 2026 10:55 am |
|
|
Yes.
Very true.
Sometimes the problem can be one that you have no control over though.
I've seen a couple of chips, which if you put a logic analyser on the timings
do things that are technically not compliant with I2C specs, and on one
of these at least, the software I2C implementation allowed it to work. |
|
 |
Woody
Joined: 11 Sep 2003 Posts: 92 Location: Warmenhuizen - NL
|
|
Posted: Thu Oct 01, 2026 4:58 am |
|
|
I find this an interesting discussion. Instinctively to me the HW implementation would always be better as this uses the module that Microchip specially made for that purpose, in contrast to the bit-banging of the CCS SW implementation. But reading this thread there are indications the SW implementation would be better?
The CCS HW implementation leaves something to be desired. At the moment I'm working on a project that is to become an I2C client. A quite basic client that controls a small DC motor assembly with a couple of one-byte commands. No requests for status code returns (yet:)
I used the CCS example EX_SLAVE_K42.C as a start but could not get that to function reliably. It did receive commands, but it kept on hanging the I2C module whenever I sent illegal addresses or too many data fields from the master (an Aardvark) to the client.
I then decided to forsake the #INT_I2C driven i2c_isr_state() and i2c_read() statements and try to roll my own. A very simple interrupt routine for #INT_I2C1RX that only reads I2C1RXB whenever there is data in RXBF seems to have solved this for me. Now I can fire any address or extra data on the bus without hanging the client I2C module.
This makes me think that either I misunderstand the way these CCS I2C functions work (happens a lot) or that these functions do not work optimally with the new I2C modules. |
|
 |
asmallri
Joined: 12 Aug 2004 Posts: 1678 Location: Perth, Australia
|
|
Posted: Thu Oct 01, 2026 5:28 am |
|
|
Well... I always use HW where it exists and the ports are available. When building a device / product that must run reliably and be able to recover itself then I build the ability into the product to either power cycle the power to all I2C slave devices or, if the the slaves are all PICs and, if possible, a common reset line under the control of the master to reset all slave PICs
I find the slave problem is the most difficult to address. When recovering the I2C bus or busses I also do a bit toggle I2C bus sequence during the recovery process before enabling the I2C master peripheral. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
 |
|
|
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
|