Searching \ for '[PIC]: PIC24 I2C module question' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: massmind.org/techref/i2cs.htm?key=i2c
Search entire site for: 'PIC24 I2C module question'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: PIC24 I2C module question'
2009\06\17@104319 by Mark E. Skeels

flavicon
face
Hi, List,

I am working with the PIC24HJ64GP210, C30 and the 16 bit Peripheral
library I2C functions.

I am trying to write/read a Maxim DS1337 RTC chip.

I started with some sample code for interfacing I2C EEPROMs and now have
the code below.

I have read the data sheet and user's guide but I don't yet fully
understand how to configure all of the control bits, so I gave it my
best shot.

/_*My problem:*_/ At line /_*1*_/ below, the I2C peripheral clocks only
8 times after start condition, so I never see the ACK from the slave DS1337.

Both of the following checks for TBF and ACK fall through and at line
*/_2_/* the function MasterWriteI2C1 returns a -1, indicating a bus
collision.

/_*My Question:*_/ How do I get the I2C peripheral to clock out the 9th
time so I can get the ACK bit from the DS1337?

Many thanks,
Mark

/***************************************************************
* Write a block of chars into the Maxim DS1337 RTC I2C device.
*
* I2CAddress contains internal starting memory location of RTC
* p_I2CWriteBlock points to first location of a block of chars
* BlockLen contains number of characters in the data block
* I2CDevAddress contains I2C device address
***************************************************************/
void I2CWriteBlock(unsigned char I2CAddress, unsigned char
*p_I2CWriteBlock, unsigned int BlockLength, unsigned char I2CDevAddress)
{
unsigned char i, I2CResult;
unsigned int config1;

//**** begin test code to fill the array with know data
unsigned char *p_TempBlock;
p_TempBlock=p_I2CWriteBlock;

for (i=0; i<BlockLength; i++)
{
*p_TempBlock = 0xad;
p_TempBlock++;
}
//*** end test code.

/* Configure I2C for 7 bit address mode 400 KHz operation.....??*/
config1 = (
I2C1_ON & I2C1_IDLE_CON & /*I2C1_CLK_HLD &*/
I2C1_IPMI_DIS & I2C1_7BIT_ADD &
I2C1_SLW_EN & I2C1_SM_DIS &
I2C1_GCALL_DIS & I2C1_STR_DIS &
I2C1_NACK & I2C1_ACK_EN & I2C1_RCV_DIS &
I2C1_STOP_DIS & I2C1_RESTART_DIS &
I2C1_START_DIS
);

//Enable I2C module 1 for use.
OpenI2C1( config1 , BRG_VAL ); //BRG_VAL is a constant;currently gives
~330 KHz bus speed
asm("nop"); //asm's help with breakpoint debugging using Pickit 3

//Wait for bus to become available
IdleI2C1();
asm("nop");

// Set a start condition on the bus
StartI2C1();
asm("nop");

//wait for start sequence to finish...
while(I2C1CONbits.SEN );
asm("nop");

// Write Slave address and set master for transmission
/_*1*_/ I2CResult=MasterWriteI2C1((I2CDevAddress << 1) & 0xfe);
asm("nop");

// Wait till I2C device address is transmitted
while(I2C1STATbits.TBF);
asm("nop");

//wait for the ACK...(it should be low so wait while high)
while(I2C1STATbits.ACKSTAT);
asm("nop");

// Set the starting location in the I2C device to be written
/_*2*_/ I2CResult=MasterWriteI2C1(I2CAddress);
asm("nop");

//Wait till I2C device address is transmitted
while(I2C1STATbits.TBF);
asm("nop");

//wait for the ACK...(it should be low so wait while high)
while(I2C1STATbits.ACKSTAT);
asm("nop");

//write the data
for (i=0; i<(BlockLength); i++)
{
asm("nop");
//Write a byte
I2CResult=MasterWriteI2C1(*p_I2CWriteBlock);
asm("nop");

/* Wait till I2C device address is transmitted */
while(I2C1STATbits.TBF);
//wait for the ACK...(it should be low so wait while high)
asm("nop");

//wait for ACK
while(I2C1STATbits.ACKSTAT);
asm("nop");

//next byte
p_I2CWriteBlock++;
}
asm("nop");

// Set a stop condition on the bus
StopI2C1();
asm("nop");

//Close I2C module 1
CloseI2C1();
asm("nop");
}

2009\06\17@114102 by Mark E. Skeels

flavicon
face
Update.

I inserted a delay after the first function call like this:

// Write Slave address and set master for transmission
I2CResult=MasterWriteI2C1((I2CDevAddress << 1) & 0xfe);
asm("nop");


for (temp=0; temp<1000; temp++)
{
}

Now I am getting the 9th (ACK) clock.

Inserting these delays throughout allowed me to get all the write
function calls to complete.

Maybe it's some kind of interaction with the Picket 3 and MPlab.

Or maybe I'm checking the wrong flag?

Mark

Mark E. Skeels wrote:
{Quote hidden}

2009\06\17@121527 by Vitaliy

flavicon
face
Mark E. Skeels wrote:
> Update.
>
> I inserted a delay after the first function call like this:
>
> // Write Slave address and set master for transmission
> I2CResult=MasterWriteI2C1((I2CDevAddress << 1) & 0xfe);
> asm("nop");
>
>
> for (temp=0; temp<1000; temp++)
> {
> }
>
> Now I am getting the 9th (ACK) clock.
>
> Inserting these delays throughout allowed me to get all the write
> function calls to complete.
>
> Maybe it's some kind of interaction with the Picket 3 and MPlab.

Have you tried reducing the delay? Another thing to try is to program the
circuit in Release mode, and see if the problem still occurs (this would
eliminate Pickit/MPLab as the source of the problem).


> Or maybe I'm checking the wrong flag?

Could it be that you're not sending the stop bit?

Vitaliy

2009\06\17@121807 by Vitaliy

flavicon
face
Mark E. Skeels wrote:
> /* Configure I2C for 7 bit address mode 400 KHz operation.....??*/
> config1 = (
> I2C1_ON & I2C1_IDLE_CON & /*I2C1_CLK_HLD &*/
> I2C1_IPMI_DIS & I2C1_7BIT_ADD &
> I2C1_SLW_EN & I2C1_SM_DIS &
> I2C1_GCALL_DIS & I2C1_STR_DIS &
> I2C1_NACK & I2C1_ACK_EN & I2C1_RCV_DIS &
> I2C1_STOP_DIS & I2C1_RESTART_DIS &
> I2C1_START_DIS
> );

OT: This sort of convoluted config code is one big reason we avoid using
Microchip libraries, and write our own.

Vitaliy

2009\06\17@123025 by Mark E. Skeels

flavicon
face

Hi, Vitaly; thanks for responding.

Vitaliy wrote:
{Quote hidden}

Yep, I tried reducing the delay to 100 but it was too short and the
problem re-occurred. I'm sure this delay is unnecessary and I'm just not
checking the correct bit or something.

I think there was some issue with the Picket 3 when setting breakpoints
but now I can get correct operation as long as I put the breakpoints in
the "right" places.
>> Or maybe I'm checking the wrong flag?
>>    
>
> Could it be that you're not sending the stop bit?
>  
I now have full, error free communication. The only thing I did was
insert delays at judicious spots in the code to allow the  actions
specified by the function calls time to occur.

So I am sure  stop bits and such are OK.
> Vitaliy
>
>  
Mark

2009\06\17@171745 by William \Chops\ Westfield

face picon face

On Jun 17, 2009, at 7:42 AM, Mark E. Skeels wrote:

> /* Configure I2C for 7 bit address mode 400 KHz operation.....??*/
> config1 = (
> I2C1_ON & I2C1_IDLE_CON & /*I2C1_CLK_HLD &*/
> I2C1_IPMI_DIS & I2C1_7BIT_ADD &
> I2C1_SLW_EN & I2C1_SM_DIS &
> I2C1_GCALL_DIS & I2C1_STR_DIS &
> I2C1_NACK & I2C1_ACK_EN & I2C1_RCV_DIS &
> I2C1_STOP_DIS & I2C1_RESTART_DIS &
> I2C1_START_DIS
> );

Shouldn't those '&'s be '|'s ?

BillW

2009\06\18@092519 by Mark E. Skeels

flavicon
face
Shouldn't those '&'s be '|'s ?

BillW


..from the MChip help file...
************************************************


 2          Using Library Functions in Your Code



Library routine parameters can be constructed using either AND based
mask or AND_OR based mask setting. For more information on these masks,
see 16-bit Peripheral Libraries
<file:///C:/Program%20Files/Microchip/MPLAB%20C30/docs/16-bit%20Peripheral%20Libraries.htm>.



Examples of use for both the methods are below.



*Example of Use ( AND mask )*

* *

#include<i2c.h>

void main(void )

{

 unsigned int config2, config1;

 unsigned char *wrptr;

 unsigned char tx_data[] = {'M','I','C','R','O','C','H','I','P','\0'};

 wrptr = tx_data;

 /* Baud rate is set for 100 Khz */

 config2 = 0x11;

 /* Configure I2C for 7 bit address mode */

 config1 = (I2C_ON & I2C_IDLE_CON & I2C_CLK_HLD &

            I2C_IPMI_DIS & I2C_7BIT_ADD &

            I2C_SLW_DIS & I2C_SM_DIS &

            I2C_GCALL_DIS & I2C_STR_DIS &

            I2C_NACK & I2C_ACK_DIS & I2C_RCV_DIS &

            I2C_STOP_DIS & I2C_RESTART_DIS &

            I2C_START_DIS);

*****************************

Mark

More... (looser matching)
- Last day of these posts
- In 2009 , 2010 only
- Today
- New search...