|
|
View previous topic :: View next topic |
Author |
Message |
Manu59114
Joined: 22 Jan 2018 Posts: 34 Location: North of France
|
New I2C_Transfer _in Out built-in function |
Posted: Tue Jun 25, 2019 9:17 am |
|
|
Hello to all!!
I remember that CCS add new built-in function to use I2C.
i2c_transfer(), i2c_transfer_out() and i2c_transfer_in()
I tried some tests and it seems better because this function don't lockup the i2C bus.
But how can i use the I2C_Transfer_In built in function to do that:
Code: |
i2c_start();
i2c_write(0xa1);
data1 = i2c_read(TRUE);
data2 = i2c_read(FALSE);
i2c_stop()
|
My question is about the TRUE(ACK) and FALSE(NACK).
Does the new function do it automatically?
FYI, I tried the code below but it doesn't work.
Code: |
unsigned int8 rData[2];
I2C_Transfer_In (I2C_STREAM1, 0x51, rData, 2);
|
Strange behavior and random reset after compile!
or to do this (Ttelmah code from SSD1306 driver)
with the built-in i2c_transfer_out() function?
Code: |
i2c_start (I2C_Stream1);
i2c_write (I2C_Stream1,SSDADDR) == 0) //select the display
i2c_write (I2C_Stream1,COMMAND_ONLY); //we are sending a command
for (ctr=0;ctr<number;ctr++)
{
I2c_write(I2C_Stream1,commands[ctr]);
}
i2c_stop(I2C_Stream1);
|
Thank you very much for your comments!
Wish you a great day
MAnu _________________ CCS + ICD3 + PIC18F46K80 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Jun 25, 2019 11:07 am |
|
|
The I2C_transfer function is built specifically for chips that have the
block transfer I2C peripheral. I have no idea if it will work on standard
chips. So big question 'what chip are you using'?.
Honestly if you don't have a chip that requires this, use the standard
functions.
Even if your chip needs this function, consider reconfiguring
temporarily to use software I2C, if you need to test the ACK.
The function transfers a block of data. Yes it does automatically handle the
ACK/NACK (read the data sheet on the peripheral which does this).
The transfer count needs to include the address byte. So to send two bytes
you need a transfer count of 3.
In the case of the SSD function you show, the transfer would have to
be of number+2 bytes, and you would have to build an array containing
the extra 'COMMAND_ONLY' byte in front of the data bytes. |
|
|
Manu59114
Joined: 22 Jan 2018 Posts: 34 Location: North of France
|
|
Posted: Tue Jun 25, 2019 3:39 pm |
|
|
From CCS C web site:
Because these functions are supported on all devices, CCS recommends using them instead of the legacy functions for developing code making the code portable to all devices. Another advantage to using these functions, compared to the legacy functions, is that they perform all the I2C steps in a single function call instead of multiple function calls.
Chip used is: dspic33ep512mu810 _________________ CCS + ICD3 + PIC18F46K80 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Jun 25, 2019 10:39 pm |
|
|
I know. However they were created to allow support for the chips that
don't support the older functions, and don't actually allow some things
that the old functions can do. Personally I consider them more likely to
lead to trouble than the standard functions, and should really only be
used on the chips that can't use the standard routines. They do
lack some capabilities, so (for instance), you can't implement PCM_
Programmer's I2C scanner using these. They actually replicate the
functions being offered on chips like the Arduino (which is probably
the second reason they were introduced), and it is interesting to look
at the forums for these chips where you find people having to fiddle
with the hardware to get round the limitations of these routines...).
Just like when #USE SPI was introduced, I believe we need to wait for
a few dozen compiler versions to be confident of the abilities and
restrictions the new functions bring.
Internally on chips using the standard peripheral on 16/18's they function
identically to the older routines. I haven't looked on the DsPIC's though,
and given these do have a peripheral than can move blocks of data,
it is possible they may be more efficient on these, though it does mean
in the case you show, having to either modify every call to add the
command to the data block, or waste the time to move the data to do this.
There are a couple of threads here about using these (on chips where
they have to be used), and these explain how the count works.
I may be 'old school', but I prefer to actually be able to monitor the
hardware and know what is being done. These do not offer this (it
is amazing that they don't have a status byte returned to give some
diagnostics...). |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
|
Posted: Tue Aug 20, 2019 3:32 pm |
|
|
I found this topic while researching an issue. I see these i2c_transfer calls are available for "All devices when #USE I2C is setup for Master Mode." I take it for a device acting as an I2C slave, you'd still have to use the older calls? _________________ 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 Aug 21, 2019 12:30 am |
|
|
I must admit I can't see any possibility to use these calls for a slave device.
I can't see you would _want_ to. The whole point is a slave needs to be
able to detect that the first byte of a transfer has occurred, not package
the whole transfer as a 'block'. So I'd definitely keep to the traditional syntax
for a slave device.
I don't see these as being designed for a slave device. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 580 Location: Des Moines, Iowa, USA
|
|
Posted: Wed Dec 16, 2020 10:03 am |
|
|
I am working on a 24FJ64GA002 project that uses two IC2 interfaces - one is a Slave to a PC Master, and the other is a Master to a sub-bus of other PIC24 devices.
After much work with the Slave side, and working around some things that seem to be issues with this chip, I now have gotten to a lock on the subnet bus.
We have a few functions that talk to the subnet.
One uses i2c_transfer_out () to blast out a message. If we are writing a 7 byte message, it looks like:
Code: |
i2c_transfer_out (SUBNET_BUS, (2 * boardAddress), txBufferPtr, txBufferSize);
|
There is a corresponding read function using i2c_transfer_in ():
Code: |
i2c_transfer_in (SUBNET_BUS, (2 * boardAddress)+1, txBufferPtr, rxBufferSize);
|
(Is that +1 needed to flag this as a read??? That's what is in the code I am working with.)
We also have third function that does the I2C transfer manually:
Code: |
i2c_start (SUBNET_BUS);
i2c_write (SUBNET_BUS, (2 * boardAddress)+1);
rxBufferPtr[0] = i2c_read (SUBNET_BUS, ONE);
rxBufferPtr[1] = i2c_read (SUBNET_BUS, ONE); // size of message payload
rxBufferSize = HEADER_SIZE + rxBufferPtr[1] + CHECKSUM_SIZE;
for (int idx=2; idx < rxBufferSize - 1; idx++)
{
rxBufferPtr[idx] = i2c+read (SUBNET_BUS, ONE);
}
// Read the last byte but don't ACK.
rxBufferPtr[idx] = i2c_read (SUBNET_BUS, ZERO);
i2c_stop (SUBNET_BUS);
|
My questions are:
1) Does i2c_transfer_in end early if a stop bit is detected? i.e., if I do this:
i2c_transfer_in (SUBNET_BUS, address, bufferPtr, 10); // read 10 bytes
...and the Master only writes 3, will this hang, or will it see the stop bit and exit? I notice it returns status of ACK vs NAK, and no way to know how many bytes were actually read.
2) When using the manual Master read loop, if the slave does its initial address read with clock stretching...
Slave: i2c_read (BUS, 2);
...(getting response message ready, takes a few...)
i2c_writes --- to send back data
If it didn't write as much data as the Master PIC was expecting, is there a way to detect that on the Master side other than polling for the STOP bit? I plan to add the stop bit detection code today for that one.
But on the i2c_transfer_in I wonder if it takes care of that since I can't change 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. |
|
|
|
|
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
|