|
|
View previous topic :: View next topic |
Author |
Message |
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
24EP256GP202 polled I2C not seeing the start bit? |
Posted: Mon Dec 16, 2024 9:45 am |
|
|
I have some polled I2C code that works on two other PIC24 chips we use, but on the 24EP256GP202 I am seeing the chip ACK the address, but the code never sees a start bit (I also checked the "incoming IRQ" bit).
I setup the I2C and define some register bits like this:
Code: | #use i2c (SLAVE, I2C1, FORCE_HW, stream=SYSTEM_BUS, address=200)
// IC2C3STAT - sto(P) bit for status.
#word I2C1STAT = getenv("SFR:I2C1STAT")
#bit TBF = I2C1STAT.0 // bit 0 - transmit buffer full status
#bit RBF = I2C1STAT.1 // bit 1 - receive buffer full status
#bit RW = I2C1STAT.2 // bit 2 - read/write information
#bit S = I2C1STAT.3 // bit 3 - start
#bit P = I2C1STAT.4 // bit 4 - stop
#word IFS1 = getenv("SFR:IFS1")
#bit I2C_SYSTEM_BUS_IRQ_PENDING_BIT = IFS1.0 // bit 0 - slave I2Cx IRQ status
|
Some of the boards have to read a hex switch to determine what I2C address to use, so there is an Init() routine that does this:
Code: |
// Initialize and enable with baud rate specified in #USE I2C directive.
i2c_init (SYSTEM_BUS, 1);
i2c_slaveaddr (SYSTEM_BUS, xxx);
|
Then I have common code used by four different boards (using three different PIC24 variants) that looks like this:
Code: | unsigned int i2cSlaveReceive (void *buffer, size_t size)
{
unsigned int bytesTransferred = 0;
// NULL check.
if ((buffer == NULL) || (size == 0)) return 0;
// There is a bug in the 24FJ64GA002 which misses the
// first Start bit and Event Interrupt Flag Status.
do
{
// Wait for START bit
while (S == 0);
// Wait for first address byte so we can tell if this is a Read or Write.
while (I2C_SYSTEM_BUS_IRQ_PENDING_BIT == 0);
// Do not clear. We may need it pending for main loop below.
// If this is a Write to Slave, we are done here.
if (RW == 0) break;
|
I see in my comments that there was an errata about missing the first S and IRQ bits on 24FJ64GA002, but I did not see a similar note for this PIC24.
When the Saleae logic analyzer is capturing, it shows the write to this address (100) ACKd, but the code remains blocked polling the S start bit.
As a test, I commented that while() out and then it will stick at the IRQ polling bit.
This code was tested pretty heavily on a different PIC24 three years ago, but now I am trying to get it implemented on our other processors.
OF NOTE: If I remove the "i2c_slaveaddr()" call (not needed for this board since the I2C address will not change), it then passes the S check and hangs at the IRQ bit check.
Anyone familair with an issue on this PIC24 that could cause the S bit to not be getting toggled?
Thanks, much. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002.
Last edited by allenhuffman on Mon Dec 16, 2024 10:20 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Dec 16, 2024 10:17 am |
|
|
You don't show the 'PIN_SELECT settings for this. Possible you have
something wrong here???
Also ADC settings. Remember these can prevent digital I/O on a pin.
The I2C on this chip has address masking. Worth manually disabling
this and see what happens. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
|
Posted: Mon Dec 16, 2024 10:56 am |
|
|
Ttelmah wrote: | You don't show the 'PIN_SELECT settings for this. Possible you have
something wrong here???
Also ADC settings. Remember these can prevent digital I/O on a pin.
The I2C on this chip has address masking. Worth manually disabling
this and see what happens. |
No PIN_SELECT on this board -- just using the defaults. Is this something that should be specified on every system, and we've just gotten lucky?
What should I look for in regards to ADC? We do not use any analog pins on this particular board, so perhaps there is a #FUSES I need to set as well? _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
|
Posted: Mon Dec 16, 2024 11:24 am |
|
|
Aha...
Code: | // SCL=pin - Specifies the SCL pin (pin is a bit address)
// SDA=pin - Specifies the SDA pin
#use i2c (SLAVE, I2C1, SCL=PIN_B8, SDA=PIN_B9, FORCE_HW, stream=SYSTEM_BUS, address=xxx)
|
It seems to be working, but it was also working last week without this. I just hadn't been able to get it working this morning.
I'll check the other I am having issues with and see if that helps.
What is it using if I do not specify? I thought I2C1, etc. would take care of it? _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
|
Posted: Mon Dec 16, 2024 11:32 am |
|
|
Well this is odd... This line works when used in the bootloader code (0x0-0x1fff, plus fuses):
Code: | #use i2c (SLAVE, I2C1, SCL=PIN_B8, SDA=PIN_B9, FORCE_HW, stream=SYSTEM_BUS, address=EXCITER_I2C_ADDRESS) |
But when I build the app (0x2000-end, no fuses), I get a warning:
Code: | *** Error 99 "..\Common\inc\Boards.h" Line 212(9,109): Option invalid Wrong pins for H/W |
It's going to be a fun week, I can tell. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Dec 16, 2024 12:51 pm |
|
|
These are ASCL1, and ASDA1. _Alternative_. You have to set the bit to
map them to these pins. Look at register 27-5. What is happening is the
bootloader 'knows' you are using the alternative pins, so sets the fuse
for this, but the main code does not know this fuse is set...... |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
|
Posted: Mon Dec 16, 2024 1:08 pm |
|
|
Ttelmah wrote: | These are ASCL1, and ASDA1. _Alternative_. You have to set the bit to
map them to these pins. Look at register 27-5. What is happening is the
bootloader 'knows' you are using the alternative pins, so sets the fuse
for this, but the main code does not know this fuse is set...... |
We do use one of the ALT I2C things on one of the boards, so it is the only one where that is specified.
While I know what we do now "works" because it has been in use for many years, is this something that I should update the code to specify to "be correct"? _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Dec 17, 2024 2:13 am |
|
|
Question. Is that I2C line in the bootloder you are actually using???
If not, you need to explicitly add the ALTI2C1 fuse to the bootloader.
Now with that set, I suspect if you use the I2C1 setting without pins,
it should work.
If you have got that I2C setup in the bootloader, then it should work.
The problem otherwise is that setting I2C1 in the main uses the default
hardware pins, since the main cannot change this fuse. Hence it is not
working on the alternate pins. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
|
Posted: Tue Dec 17, 2024 8:25 am |
|
|
Pushing some fuses into the "application" made this project run as expected. As it stands right now, I have two projects that seem to be working as expected, and two that are still having odd I2C (maybe) issues:
24FJ64GA002 - working.
24EP256GP202 - working
24FJ64GA002 - not working (it makes use of the second I2C bus)
24FJ256GA106 - not working
It is frustrating that I was able to get a 24FJ64GA002 board working, but another board also using the 24FJ64GA002 is not.
I did some work yesterday and got all the fuses to match between the Bootloader build and the application build. I made files looking at what is in the .lst and .hex files, like this:
Code: |
--- 'A' Fuses:
Configuration Fuses:
Word 1L: 376D WPOSTS14 WDT32 WINDIS NOWDT ICSP1 DEBUG NOWRT NOPROTECT NOJTAG
H: 0000
Word 2L: FB15 XT NOALTI2C1 IOL1WAY OSCIO CKSFSM PR_PLL SOSC_SEC WUT_DEFAULT IESO
H: 0000
Configuration Words
00ABFC: 00FFFB15 00FF376D
--- Bootloader Fuses:
Configuration Fuses:
Word 1L: 3F6D WPOSTS14 WDT32 WINDIS NOWDT ICSP1 NODEBUG NOWRT NOPROTECT NOJTAG
H: 0000
Word 2L: FB15 XT NOALTI2C1 IOL1WAY OSCIO CKSFSM PR_PLL SOSC_SEC WUT_DEFAULT IESO
H: 0000
Configuration Words
00ABFC: 00FFFB15 00FF3F6D
|
...so I suppose the issue is not related to fuses anymore. Though this has been a very good learning exercise. I inherited five existing boards that had been in use, and have really only done one "ground up" board so far, which is the first one I used my bootloader code in. I had zero problems with that one, but it was all SPI parts and used a Wiznet ethernet part -- which still makes me think there is some I2C config stuff the compiler does automatically that I do not understand, and is not getting done after my project changes.
Always fun. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
|
Posted: Tue Dec 17, 2024 9:27 am |
|
|
I forgot to mention - I got the previous board running by disabling a timer interrupt that was not being used (counting for something no longer active).
I just did a similar test with another board having problems and now the I2C is running fine in the bootloader-loaded app.
The breakpoints in the timers were being hit, but something must be misconfigured and it messes up the I2C interrupt or something.
Any suggestions are greatly appreciated. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
|
Posted: Tue Dec 17, 2024 10:17 am |
|
|
Well, odd. This appears to be the cause of the issues with the second board:
Code: | enable_interrupts (INT_TIMER5); |
Something needs to be configured or changed for my application that must have been automatically being done when it was built as a standard app starting at memory 0x0. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Wed Dec 18, 2024 2:25 am |
|
|
Possibly sounds as if the timer interrupt was not exiting.
At least you have found it. Would be nice though to work out what it
really was about that interrupt causing the problem. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
|
Posted: Wed Dec 18, 2024 11:33 am |
|
|
There is an underlying problem I do not understand, but I have workarounds.
During my code inspection, I was reminded by my comments of a few issues:
1) One (maybe two) of our PIC24s have bugs in the timers. Even doing a simple "hello world" with timer code generated by the CCS Wizard, or by the #use, makes two timers that run too fast, but others are accurate. I even used a third-party website that generated the register values, and they do the same. I have gone back and re-tested this a few months ago and the problem seems legit. So I use one working timer and call the other routines from it (we use too many timers in this code anyway).
2) One of the timers causes the ICD output to be corrupt. That was a pain to find, and I did a similar workaround (does not effect anyone in the world except developer trying to use ICD RS232 console mode).
3) I had a new issue with firmware locking up as soon as the IRQ was enabled (I2C ISR). I believe this was caused by some incoming byte being stuck in the chip and jumping in to the ISR immediately where it would never see a stop bit or the next byte. I manually clear that IRQ pending bit and that resolved that.
But clearly, there is much more understanding I need to have ;-) _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Wed Dec 18, 2024 12:41 pm |
|
|
On the I2C, use the NOINIT option, and check the lines are both high
before initialising the peripheral. If not, manually toggle the clock line
nine times, and then try again.
Once you have multiple chips or boards linked there always needs to
be handling to cope with some parts being slower than others. I do the
same on RS232 and SPI. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
|
Posted: Fri Dec 20, 2024 7:34 pm |
|
|
Ttelmah wrote: | On the I2C, use the NOINIT option, and check the lines are both high
before initialising the peripheral. If not, manually toggle the clock line
nine times, and then try again.
Once you have multiple chips or boards linked there always needs to
be handling to cope with some parts being slower than others. I do the
same on RS232 and SPI. |
Thanks! Our Application firmware does a clock reset on startup, but that is likely well after the IRQs are initialized. I will check for that. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
|
|
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
|