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 support@ccsinfo.com

dealing with clock stretching using ccs i2c functions

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



Joined: 09 Jul 2009
Posts: 11

View user's profile Send private message

dealing with clock stretching using ccs i2c functions
PostPosted: Thu Jul 16, 2009 7:15 am     Reply with quote

Hi all,

I am currently trying to convert some very elegantly written master I2C assembler code written for a pic16f960 over to C. The original assembly routines were based on the Microchip app note: AN554 Software Implementation of I2C a Bus Master.

The slave device I am trying to talk to uses clock stretching to delay the clock: From slave device spec:

"The TVP5150AM1 decoder requires delays in the I2C accesses to accommodate its internal processor's timing. In accordance with I2C specifications, the TVP5150AM1 decoder holds the I2C clock line (SCL) low to indicate the wait period to the I2C master."

For simplicity I am trying to start off with the i2c functions provided by the CCS compiler to get some basic functionality working. Unfortunately the CCS i2c functions do not seem to deal with clock stretching. Is this the case? Is there anyway of using the CCS I2C functions to create a simple I2C master and account for clock stretching by the slave?

I have include my simple code below. It is far from elegant but at this point I am just trying to write to a specific address in the slave device.
I can see the slave address going out on the logic analyzer so I know the program is partially working.

Any suggestions would be much appreciated!!

Cheers
Mike

Code:
#include <16F690.h>
#device adc=8

#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES PUT                      //No Power Up Timer
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                    //No EE protection
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT

#use delay(internal=4M)
#use i2c(Master,Slow,sda=PIN_B4,scl=PIN_B6)

#include "C:\mydocs\picfware\i2c_master_trial\main.h"



void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
   setup_oscillator(OSC_4MHZ);

   // TODO: USER CODE!!
   while (1){
   i2c_start ();
   i2c_write (0xbb); // slave device address
   i2c_write (0x00); // request slave ‘internal memory address’ 0×00
   i2c_write (0x80); // write data 0x80
   i2c_stop();
   delay_us(20);
   }
}
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Jul 16, 2009 9:49 am     Reply with quote

Because you didn't specify FORCE_HW in #use i2c, a software master is implemented from your code. I'm not sure, if it's also supporting clock stretching. The PIC16F hardware I2C interface should support it.
mikem



Joined: 09 Jul 2009
Posts: 11

View user's profile Send private message

PostPosted: Thu Jul 16, 2009 10:03 am     Reply with quote

Hi FvM,

from reading the pic16f690 datasheet I was under the impression that any master functionality had to be implemented in software.
The pic16f690 only has an SSP hardware module and not the MSSP module that some other microchip parts have. Unless I am missing something?

Cheers
Mike
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 16, 2009 11:48 am     Reply with quote

Quote:
The TVP5150AM1 decoder

I've done a driver for this. Here are the low-level register r/w routines
and an init routine. There are other routines, but this will get you started.
The init routine has some experimental settings in it because the product
was still under development at the time. But I believe the uncommented
settings do work.
Code:

// TVP5150A.c

// Notes:
// The T.I. FAQ for this chip says the i2c latency can be up to
// one Horizontal line time (64 us for PAL, 63.5 us for NTSC).
// They say that the i2c stop function must check the SCL signal,
// and not return until it goes high.  (ie., the TVP5150A does
// clock stretching).   I checked the .LST file and the CCS compiler
// does this for the i2c_stop() function.  (At least they do it
// for software i2c, and that's what we're using on this board).

//-----------------------------------------
// Write an 8-bit value to the specified TVP5150A register.

void write_TVP5150A_reg(char reg_addr, char value)
{
i2c_start();
i2c_write(TVP5150A_I2C_WRITE_ADDRESS);
i2c_write(reg_addr);
i2c_write(value);
i2c_stop();
}

//-----------------------------------------
// Read an 8-bit value from the specified TVP5150A register.
// The method shown below is peculiar in that it doesn't do
// a "re-start", but this is how the data sheet says to do it.

char read_TVP5150A_reg(char reg_addr)
{
char value;

i2c_start();
i2c_write(TVP5150A_I2C_WRITE_ADDRESS);
i2c_write(reg_addr);
i2c_stop();

i2c_start();
i2c_write(TVP5150A_I2C_READ_ADDRESS);
value = i2c_read(0);
i2c_stop();

return(value);
}

//-----------------------------------------
void init_TVP5150A(void)
{
//write_TVP5150A_reg(0x03, 0x09);

// CAUTION:
// There are restrictions on the settings for
// registers 0x03 and 0x0F regarding the VBLANK/GPCL pin.
// Some settings will cause the TVP5150A to appear to stop
// working.   The data sheet hints at this.  I've seen it.
// The following settings work OK. 
write_TVP5150A_reg(0x03, 0xEF);  // Was 0x2F

write_TVP5150A_reg(0x0F, 0x0A);  // Enable pin 27 for VBLANK/GPCL
//write_TVP5150A_reg(0x0F, 0x08);


// 8-17-05
// Disable adaptive line filter and comb filter on
// the receiver board, per [mgr].  This removes artifacts
// due to the 3-line filtering with lines that are no
// longer properly adjacent, due to the scrambling.
// The default value is 0x0C which enables both filters.

// *** TESTING ***  COMMENTED OUT FOR THE PASSTHRU TEST.
//write_TVP5150A_reg(0x1A, 0x00);


//  Tell it to expect a pedestal.  By doing this, we prevent
//  the TVP5150A from inserting a pedestal.
write_TVP5150A_reg(0x07, 0x20);

}

//-----------------------------------------
void display_TV5150A_reg(int8 addr)
{
printf("%02x %02x\n\r", addr, read_TVP5150A_reg(addr));
}

//-----------------------------------------
void dump_TVP5150A_regs(void)
{
char i;

for(i = 0; i <= 0x1E; i++)
    display_TV5150A_reg(i);

display_TV5150A_reg(0x28);

for(i = 0x2c; i <= 0x2F; i++)
    display_TV5150A_reg(i);

for(i = 0x80; i <= 0x8C; i++)
    display_TV5150A_reg(i);

for(i = 0xC0; i <= 0xCF; i++)
    display_TV5150A_reg(i);

}

Guest








PostPosted: Fri Jul 17, 2009 1:53 am     Reply with quote

Sweet!! Thanks very much PCM programmer. This should definitely help!!
Thanks for the code.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Jul 17, 2009 2:11 am     Reply with quote

Quote:
from reading the pic16f690 datasheet I was under the impression that any master functionality had to be implemented in software.
I2C master operation is explicitely discussed in the datasheet. At least part of the master functionality is handled by the hardware when selecting FORCE_HW in CCS C.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 17, 2009 11:03 am     Reply with quote

The 16F690 says the following, but it's referring to Multi-Master mode.
Quote:
13.13 Master Mode
Master mode of operation is supported in firmware
using interrupt generation on the detection of the Start
and Stop conditions.

In normal i2c Master Mode, in a PIC with an SSP module (not MSSP)
the compiler will generate "bit banging" code only, with no hardware
support. That's the only way it can be done.

If "FORCE_HW" is used in the #use i2c() statement, and the PIC only
has an SSP module, the compiler will generate incorrect code. It won't
work. It tries to send a byte by writing to the SSPBUF register, but that
register isn't functional in Master mode, because the PIC only has an
SSP module. Also, it tries to setup the hardware i2c baudrate generator
by writing to SSPADD, but it can't work, because that feature isn't
available in an SSP module (only in MSSP).
mikem



Joined: 09 Jul 2009
Posts: 11

View user's profile Send private message

PostPosted: Mon Jul 20, 2009 4:15 am     Reply with quote

Hi PCM programmer and FVM.

Thanks for your help.

Cheers
Mike
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