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

I need a help Understanding INT_SSP

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



Joined: 09 Jul 2004
Posts: 70

View user's profile Send private message

I need a help Understanding INT_SSP
PostPosted: Thu Apr 12, 2007 9:51 am     Reply with quote

I am trying to use the a PIC16F819 to be a bridge between a SMBUS hose and an SMBUS battery. I have code set up so that i can be the Master and talk to the battery, no problems here, i have done this many times before. However, the new part for me is having the PIC be a slave and listen for the Host. I have the INT_SSP interrupt looking for the HOst to call the address (0x16). I have used the EX_Slave as my base line. However, i am having problems with this. I am not sure that i understand how this routine is working. I have read almost every thread on this forum that i can find about the INT_SSP and EX_Slave, and i am not seeing how after the address is recognized, what needs to happen next. I have attached my code so far. What i need to do is look for the host to tell me which register it wants from the SMBUS data set. I then swtich to MASter and talk to the smbus battery. Then i switch back to slave and write the data back to the HOST. At this point, i do not seem to be able to read the requested register.
Compiler Version 4.027


#include <16F819.h>
#device adc=10
#use delay(clock=4000000, RESTART_WDT)
#fuses WDT,INTRC_IO, PUT, MCLR, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT
#use i2c(MASTER,Fast,sda=PIN_B2,scl=PIN_B5)
#include <math.h>

#use fast_io(A)
#define LED1 PIN_A0 //100% led
#define LED2 PIN_A1 //80% led
#define LED3 PIN_A2 //60% led
#define LED4 PIN_A3 //40% led
#define LED5 PIN_A4 //10-20% led, yellow
#define LED6 PIN_A6 //below 10% or fault led, red

#use fast_io(B)
#define sw_in PIN_B0 //switch
#define SMBD_E PIN_B1 //smbus data external
#define SMBD_I PIN_B2 //smbus data internal
#define SMBC_E PIN_B4 //smbus clock external
#define SMBC_I PIN_B5 //smbus clock internal

#define INTS_PER_SECOND 15


////////////////////////////////////////////////////////////////////////////////

BYTE address, buffer[0x10];
char i,loop,int_count,bus_free,fault;
int lb_current,hb_current,count,lsb,msb;
long time1,seconds,voltage,percent,status,temperature,value;
signed long current;


////////////////////////////////////////////////////////////////////////////////
#int_rtcc
clock_isr()
{
if(--int_count==0) //decrement counter until 0
{
++seconds; //count up seconds
int_count=INTS_PER_SECOND; //reset counter
if (seconds>=65000)
seconds=65000;
}
}
////////////////////////////////////////////////////////////////////////////////
void read_sm_percent (void)
{
i2c_start(); //read capacity
i2c_write(0x16);
i2c_write(0x0E);
i2c_start();
i2c_write(0x17);
percent=i2c_read(0);
i2c_stop();
}
////////////////////////////////////////////////////////////////////////////////
void read_sm_temperature (void)
{
i2c_start(); //read capacity
i2c_write(0x16);
i2c_write(0x08);
i2c_start();
i2c_write(0x17);
lsb=i2c_read();
msb=i2c_read(0);
i2c_stop();
temperature=make16(msb,lsb);
}
////////////////////////////////////////////////////////////////////////////////
void read_sm_voltage (void)
{
i2c_start(); //read capacity
i2c_write(0x16);
i2c_write(0x09);
i2c_start();
i2c_write(0x17);
lsb=i2c_read();
msb=i2c_read(0);
i2c_stop();
voltage=make16(msb,lsb);
}
////////////////////////////////////////////////////////////////////////////////
#INT_SSP
void ssp_interupt ()
{
BYTE incoming, state;

state = i2c_isr_state();

if(state < 0x80) //Master is sending data
{
incoming = i2c_read();
address = incoming;
/*if(state == 1) //First received byte is address
address = incoming;
if(state == 2) //Second received byte is data
buffer[address] = incoming;*/
#use i2c(Master,Fast,sda=PIN_B2,scl=PIN_B5)
i2c_start(); //read capacity
i2c_write(0x16);
i2c_write(address);
i2c_start();
i2c_write(0x17);
lsb=i2c_read();
msb=i2c_read(0);
i2c_stop();
value=make16(msb,lsb);
#use i2c(SLAVE,Fast,sda=PIN_B1,scl=PIN_B4,address=0x16,smbus)
i2c_write(value);
}
if(state == 0x80) //Master is requesting data
{
output_low(LED2);
#use i2c(Master,Fast,sda=PIN_B2,scl=PIN_B5)
i2c_start(); //read capacity
i2c_write(0x16);
i2c_write(address);
i2c_start();
i2c_write(0x17);
lsb=i2c_read();
msb=i2c_read(0);
i2c_stop();
buffer[address]=make16(msb,lsb);
#use i2c(SLAVE,Fast,sda=PIN_B1,scl=PIN_B4,address=0x16,smbus)
i2c_write(buffer[address]);
}
output_float(SMBC_I); //release data line
output_float(SMBD_I); //release clock line
output_float(SMBC_E); //release data line
output_float(SMBD_E); //release clock line
}
////////////////////////////////////////////////////////////////////////////////
void read_sm_current (void)
{
i2c_start(); //read capacity
i2c_write(0x16);
i2c_write(0x0A);
i2c_start();
i2c_write(0x17);
lsb=i2c_read();
msb=i2c_read(0);
i2c_stop();
current=make16(msb,lsb);
}
////////////////////////////////////////////////////////////////////////////////
void read_sm_status (void)
{
i2c_start(); //read capacity
i2c_write(0x16);
i2c_write(0x16);
i2c_start();
i2c_write(0x17);
status=i2c_read(0);
i2c_stop();
}


void main()
{
#use i2c(SLAVE,Fast,sda=PIN_B1,scl=PIN_B4,address=0x16,smbus)
output_float(SMBC_I); //release data line
output_float(SMBD_I); //release clock line
output_float(SMBC_E); //release data line
output_float(SMBD_E); //release clock line
output_high(LED1); //turn led off
output_high(LED2); //turn led off
output_high(LED3); //turn led off
output_high(LED4); //turn led off
output_high(LED5); //turn led off
output_high(LED6); //turn led off

setup_oscillator(osc_4mhz);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_8);
setup_counters(RTCC_INTERNAL,RTCC_DIV_256);
set_rtcc(0);
enable_interrupts(INT_RTCC);
ext_int_edge(0,H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
port_b_pullups(false); //added to see if this could be used on chg

set_tris_a(0b00000000);
set_tris_b(0b00000001);

loop=1; //initialize all vairables
int_count=INTS_PER_SECOND; //used for timer
seconds=0; //clear out variable
time1=30; //counter for time,30 seconds
delay_ms(1000);
//percent=0;
count=0;
bus_free=0;
fault=0;

while (TRUE)
{

delay_ms(100);
//output_low(LED1);
delay_ms(100);
// output_high(LED1);
output_float(SMBC_I); //release data line
output_float(SMBD_I); //release clock line
output_float(SMBC_E); //release data line
output_float(SMBD_E); //release clock line

}
}[/code]
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 12, 2007 11:16 pm     Reply with quote

I didn't look closely at your code. But, you are attempting to use
#use i2c() statements to switch between i2c Master and Slave modes
within your program. That won't work. When the compiler sees a
#use i2c() statement, it will only insert the code to set the Master or
Slave mode at the start of main().

If you want to change modes within your program, you must directly
write to the SSPCON register.

See how Mark does it in his multi-master code.
http://www.ccsinfo.com/forum/viewtopic.php?t=22105
This code may or may not be applicable to your needs, but at least
it will show you the idea of the need to write directly to SSPCON to
change the i2c mode.
nmeyer



Joined: 09 Jul 2004
Posts: 70

View user's profile Send private message

PostPosted: Fri Apr 13, 2007 9:26 am     Reply with quote

I do not seem to be having problems with switching the use_i2c in the program, I can switch back and forth and between the two and perform function on both, but i will look at this further and see if i need to be doing it differently.
The main issue is that i can get to the int_ssp but once i am there, i have not bee able to determine what it is doing, either my code or the ex_slave example. For the smbus, i should be looking for the host to : write slave address (0x16) (which the int_ssp detects) write data register address, write slave address write mode (0x17) and then i should be witing back the data in the data register address. The Int_ssp does not seem to get the data register address (i do a i2c_read).

Any one have suggestions?
Thanks
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