CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

New I2C_Transfer _in Out built-in function

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Manu59114



Joined: 22 Jan 2018
Posts: 34
Location: North of France

View user's profile Send private message

New I2C_Transfer _in Out built-in function
PostPosted: Tue Jun 25, 2019 9:17 am     Reply with quote

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: 19520

View user's profile Send private message

PostPosted: Tue Jun 25, 2019 11:07 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 25, 2019 3:39 pm     Reply with quote

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: 19520

View user's profile Send private message

PostPosted: Tue Jun 25, 2019 10:39 pm     Reply with quote

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: 552
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Tue Aug 20, 2019 3:32 pm     Reply with quote

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 ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Wed Aug 21, 2019 12:30 am     Reply with quote

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: 552
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Wed Dec 16, 2020 10:03 am     Reply with quote

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 ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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