|
|
View previous topic :: View next topic |
Author |
Message |
allenhuffman
Joined: 17 Jun 2019 Posts: 540 Location: Des Moines, Iowa, USA
|
|
Posted: Mon Oct 28, 2019 2:31 pm |
|
|
gaugeguy wrote: | Check the assembly code. If the bit in CCS is labeled PCIE for both I2C1CON and I2C2CON then your code is probably setting the bit in the wrong register.
You may need to use getenv to get the address for I2C2CONH and then do a #bit for the PCIE in that register manually. |
Thanks... I should have noticed by the description using I2CxCONH. I changed it to:
Code: |
// I2C2CONH - PCIE enable/disable bit, then P and S bits for status.
#word I2C2CONH = getenv("SFR:I2C2CONH")
#bit PCIE = I2C2CONH.6 // bit 6 - enable/disable
|
Now I see the bit set. I'm now working thru the interrupts to see if the Start and Stop IRQs will do what I want to do. _________________ 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 ? |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 540 Location: Des Moines, Iowa, USA
|
|
Posted: Mon Oct 28, 2019 3:10 pm |
|
|
Looks like this wasn't what I was looking for. I am now exploring this:
Code: | #bit MXMT = I2C2STAT.14 // bit 14 - TRSTAT master xmit status
|
When the master is done with the write, this clears to 0. I made my ISR check for this, and use it to flag that a message has been received. It is working great, but I'm not confident this is a proper way to do this. I don't know if I2C messages can be fragmented... Does this toggle between multiple write() commands on the Master? Or only at the end of a stop()?
Time to hook the scope back up... _________________ 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 ? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 28, 2019 4:54 pm |
|
|
Could you tell us what chip you're using, and whether this is for a Master
or Slave ? The reason is, if I Google the following I get no hits at all.
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19466
|
|
Posted: Tue Oct 29, 2019 1:46 am |
|
|
The reason is he has given the bit his own name. It is the TRSTAT bit. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19466
|
|
Posted: Tue Oct 29, 2019 7:42 am |
|
|
It's worth perhaps understanding that the standard I2C usage allows any size
'block' to be handled (up to 128 bytes). The only reason for needing to
detect 'stop', is if you want to apply some form of 'post processing' when
a block is received. Normally this is actually done by simply having an
'action' bit that the master sets to say to perform this, rather than trying
to do it automatically. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 540 Location: Des Moines, Iowa, USA
|
|
Posted: Tue Oct 29, 2019 8:44 am |
|
|
Ttelmah wrote: | It's worth perhaps understanding that the standard I2C usage allows any size
'block' to be handled (up to 128 bytes). The only reason for needing to
detect 'stop', is if you want to apply some form of 'post processing' when
a block is received. Normally this is actually done by simply having an
'action' bit that the master sets to say to perform this, rather than trying
to do it automatically. |
Yes. I am trying to implement this, rather than how our pre-existing code does it by looking at specific bytes in a payload for the length, and knowing it is done when that many have been received. I just want to make something more flexible and generic than the pre-existing hard-coded approach currently in place.
The ISR is servicing a byte at a time, and I want to detect when the master has written a message so it can then be processed.
Our system has about five unique boards with variations of PIC24, and we end up talking to stacks of other boards via a multiplexer that receives I2C commands and then passes them out on a secondary I2C bus to 8 more units. Lots and lots of things stacked together :-) The original design from several years ago was not written with this in mind, so I'm hoping to help rewrite it to be a bit more flexible and easy to modify. _________________ 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 ?
Last edited by allenhuffman on Tue Oct 29, 2019 8:52 am; edited 1 time in total |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 540 Location: Des Moines, Iowa, USA
|
|
Posted: Tue Oct 29, 2019 8:48 am |
|
|
PCM programmer wrote: | Could you tell us what chip you're using, and whether this is for a Master
or Slave ? The reason is, if I Google the following I get no hits at all.
|
I called it M XMT for Master Transmit. If I get to refactor, I will probably "clean code" it and make long, descriptive names like MasterTransmitStatus or something _________________ 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 ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19466
|
|
Posted: Tue Oct 29, 2019 9:11 am |
|
|
So, in which case just use the normal way. Change the setup to enable
interrupt on start/stop, and before doing the normal I2C handling check
for start (exit if seen), and stop (trigger your end of block code). Follow
with the standard I2C code.
The TRSTAT bit is not meant to be used for this. It is defined for master
only, and does sometimes seem to work on slave, but not guaranteed. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 29, 2019 10:27 am |
|
|
Also, changing the names of register bits makes the code much harder
to maintain. It's best to use the actual name and then add a comment
to clarify it, if necessary.
Notice how I was mystified by your bit name ? I googled it and got a
nothing-burger. A future maintainer of your code will have a hard time. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 540 Location: Des Moines, Iowa, USA
|
|
Posted: Tue Oct 29, 2019 11:49 am |
|
|
Ttelmah wrote: | The TRSTAT bit is not meant to be used for this. It is defined for master only, and does sometimes seem to work on slave, but not guaranteed. |
Is there any existing CCS code that I can use to do this? How is one supposed to even know that the master is done writing X bytes with their API? _________________ 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 ? |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 540 Location: Des Moines, Iowa, USA
|
|
Posted: Tue Oct 29, 2019 11:51 am |
|
|
PCM programmer wrote: | Notice how I was mystified by your bit name ? I googled it and got a nothing-burger. A future maintainer of your code will have a hard time. |
Excatly. That's why I would personally call it MasterTransmitStatus or something verbose. Techies love to use alphabet soup but that makes understanding code difficult -- have to consult datasheets, etc.
If you've never looked into it, check out https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882. I had never heard of this concept until my previous job, and after going in kicking in screaming for months, it finally changed my outlook on what code can be.
It's tough to honor in embedded if you are low on flash storage or clock cycles, but when that's not a barrier, it makes a great amount of sense.
Some day, I'll go back through all my GitHub stuff and "clean code" it all. Talk about alphabet soup... _________________ 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 ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19466
|
|
Posted: Tue Oct 29, 2019 1:29 pm |
|
|
Just use the P & S bits. These say whether the transfer that triggers the
interrupt was a start or stop. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19466
|
|
Posted: Thu Oct 31, 2019 1:30 am |
|
|
The way I have handled this in the past, which is simple, and works, is:
Setup standard slave interrupt.
Use standard slave interrupt handler.
Then in main code loop, test for the 'P' bit from the I2C. If this is set, call
your 'end of packet' handler code.
Nothing more is needed. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 540 Location: Des Moines, Iowa, USA
|
|
Posted: Thu Nov 07, 2019 2:18 pm |
|
|
(Edit to remove the code I found. After looking into it more, I am uncomfortable with how it mixes library calls and direct register access.) _________________ 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 ? |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 540 Location: Des Moines, Iowa, USA
|
|
Posted: Thu Nov 07, 2019 3:28 pm |
|
|
Ttelmah wrote: | The way I have handled this in the past, which is simple, and works, is:
Setup standard slave interrupt.
Use standard slave interrupt handler.
Then in main code loop, test for the 'P' bit from the I2C. If this is set, call
your 'end of packet' handler code.
Nothing more is needed. |
I found some polled Slave code that I was working with, and it was reading the P in the loop to know when to stop. It worked well, but once I tried to remove some of the other direct register reads, the P stopped working. The original author had their own i2cRead() routine that looked like a standard C read/write (buffer pointer, size to read/write).
I was trying to do this in polled mode, but I can't get the P to work. When I had other code in earlier that also checked RBF and DA bits, then the P was good. So maybe something about reading those other bits is necessary when no interrupts are in use.
Code: |
// IC2C3STAT - sto(P) and (S)tart bits for status.
#word I2C3STAT = getenv("SFR:I2C3STAT")
#bit DA = I2C3STAT.5 // bit 5 - data/address bit
#bit P = I2C3STAT.4 // bit 4 - stop
#bit S = I2C3STAT.3 // bit 3 - start
#bit RW = I2C3STAT.2 // bit 2 - read/write bit
#bit RBF = I2C3STAT.1 // bit 1 - RBF receive buffer status bit
…
while (1) // Read incoming bytes.
{
buffer[bytesRead++] = i2c_read(SYSTEM_BUS);
if (bytesRead > size)
{
break;
}
if (P == 1) // Stop?
{
break;
}
}
|
_________________ 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 ? |
|
|
|
|
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
|