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

I2C Master Slave (18F4550) once again!? [FINALLY RESOLVED]
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PICoHolic



Joined: 04 Jan 2005
Posts: 224

View user's profile Send private message

I2C Master Slave (18F4550) once again!? [FINALLY RESOLVED]
PostPosted: Fri Apr 27, 2007 12:30 am     Reply with quote

My goal is to connect 18F4550 I2C master to 18F4550 I2C slave.
I2C master is by software (it works fine with other slaves)
I2C slave is by hardware (Code taken from the example provided by CCS)

Below are the two codes.
The problem is that the master is always reading 0xFF

Master Code
Code:

#include <18F4550.h>
#device adc=8

#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN, NOPBADEN, ICPRT
#use delay(clock=48000000)
#use i2c(Master,Slow=100000,sda=PIN_C0,scl=PIN_C1)


#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#byte PORTA = 0xF80
#byte PORTB = 0xF81
#byte PORTC = 0xF82
#byte PORTD = 0xF83
#byte PORTE = 0xF84

#byte TRISE = 0xF96

#include "MDIO.h"
///////////////////////////////////////////////////////////////////////////////
// USB
#include <usb_cdc.h>
///////////////////////////////////////////////////////////////////////////////

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

///////////////////////////////////////////////////////////////////////////////
#use delay(clock=48000000)
///////////////////////////////////////////////////////////////////////////////
void main()
{
   unsigned int8 Buff[16];
   unsigned int8 BuffPointer=0;
   int16 Val;
   int8 i2cVal;
   
   MDIOPacket MDIO_P;
   
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
 
   setup_low_volt_detect(FALSE);
   setup_oscillator(False);

   delay_ms(1000);
//////////////////////////////////////////////////////////////
    Init_MDIO(&MDIO_P);
//////////////////////////////////////////////////////////////

   usb_cdc_init();
   usb_init();
   while(!usb_cdc_connected()) {}
   
   while (TRUE)
   {
      usb_task();
      if (usb_enumerated())
      {
         Buff[BuffPointer] = usb_cdc_getc();
         if (++BuffPointer == 5)
         {
            BuffPointer = 0;
            switch (Buff[0])
            {
               case 0xF0:     // Register Data
                  MDIO_P.OP = OP_REG;
                  MDIO_P.PRTAD = Buff[1];
                  MDIO_P.DEVAD = Buff[2];
                  MDIO_P.DATA_ADDR = Buff[4];
                  MDIO_P.DATA_ADDR <<= 8;
                  MDIO_P.DATA_ADDR |= Buff[3];
                  write_MDIO(MDIO_P);
               break;
                 
               case 0xF1:     // Write Data
                  MDIO_P.OP = OP_WR;
                  MDIO_P.PRTAD = Buff[1];
                  MDIO_P.DEVAD = Buff[2];
                  MDIO_P.DATA_ADDR = Buff[4];
                  MDIO_P.DATA_ADDR <<= 8;
                  MDIO_P.DATA_ADDR |= Buff[3];
                  write_MDIO(MDIO_P);
               break;
                 
               case 0xF2:     // Read Data
                  MDIO_P.OP = OP_RD;
                  MDIO_P.PRTAD = Buff[1];
                  MDIO_P.DEVAD = Buff[2];
                  Val = read_MDIO(MDIO_P);
                  usb_cdc_putc( Val & 0x00FF );
                  usb_cdc_putc( Val >> 8 );
               break;
                 
               case 0xF3:     // Post Read data + increment
                  MDIO_P.OP = OP_RDI;
                  MDIO_P.PRTAD = Buff[1];
                  MDIO_P.DEVAD = Buff[2];
                  Val = read_MDIO(MDIO_P);
                  usb_cdc_putc( Val & 0x00FF );
                  usb_cdc_putc( Val >> 8 );
               break;
                 
               case 0xF4:                         //// I2C TEST ///////////
                  i2c_start();
                  i2c_write(0xE0);
                  i2c_write(0x00);
                  i2c_start();
                  i2c_write(0xE1);
                  i2cVal = i2c_read(0);
                  i2c_stop();
                  usb_cdc_putc(i2cVal);
               break;
            }
         }
      }
   }
}


Slave Code
Code:

#include <18F4550.h>
#device adc=8

#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN, NOPBADEN, ICPRT
#use delay(clock=48000000)

#use i2c(SLAVE, SDA=PIN_B0, SCL=PIN_B1, address=0xE0)

///////////////////////////////////////////////////////////////////////////////
// USB
#include <usb_cdc.h>
///////////////////////////////////////////////////////////////////////////////
#byte SSPCON1  =  0xFC6
#bit  SSPOV    =  SSPCON1.6
///////////////////////////////////////////////////////////////////////////////
BYTE address, buffer[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8' };
//////////////////////////////////////////////////////////////////////////////
#INT_SSP
void ssp_interupt ()
{
   BYTE incoming, state;

   state = i2c_isr_state();

   if(state < 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      if(state == 1)                     //First received byte is address
         address = incoming;
      if(state == 2)                     //Second received byte is data
         buffer[address] = incoming;
   }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(buffer[address]);
   }
   
   SSPOV = 0;
}
///////////////////////////////////////////////////////////////////////////////
#use delay(clock=48000000)
///////////////////////////////////////////////////////////////////////////////
void main()
{
   unsigned int8 Buff[16];
   unsigned int8 BuffPointer=0;
   int16 Val;
   
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
 
   //setup_low_volt_detect(FALSE);
   //setup_oscillator(False);
   
   enable_interrupts(INT_SSP);
   clear_interrupt(INT_SSP);
   enable_interrupts(GLOBAL);
   
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
   
   while (TRUE)
   {
   }
}


Compiler version 4.029 Silicon revision A3 Sad
Mater is reading 0xFF instead of 0x30 ('0'). Somtimes it stalls unless i remove one of the I2C lines (obvious).

Any suggestions? I need to make it work.. It's critical Sad


Note: I've already read all the previous posts related to I2C slave!!


Last edited by PICoHolic on Thu May 03, 2007 2:51 am; edited 5 times in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 27, 2007 1:32 am     Reply with quote

You shouldn't address this post to me. You shouldn't assume that
I know the answer. Please edit the title so it's not addressed to me.
Then you might get help from other people.
PICoHolic



Joined: 04 Jan 2005
Posts: 224

View user's profile Send private message

PostPosted: Fri Apr 27, 2007 1:48 am     Reply with quote

Sorry PCM Programmer. Maybe i shouldnt do it. I removed it.
Sorry once again but i really need to make it happen.

Thank you.
PICoHolic



Joined: 04 Jan 2005
Posts: 224

View user's profile Send private message

PostPosted: Fri Apr 27, 2007 7:19 am     Reply with quote

Any one?
Sad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 27, 2007 11:36 am     Reply with quote

You have a combined "USB/i2c Master-Slave" project. I have never
done a PIC USB project. I can only help with the i2c Master-Slave
part, and then, only if it's kept simple.

If you want me to help, you need to post new test programs, with all
the USB code removed. Make it only be i2c Master-Slave code.
Cut out anything (including switch-case statements) that has anything
to do with the USB. Then test it, prove that it fails, and post it.
PICoHolic



Joined: 04 Jan 2005
Posts: 224

View user's profile Send private message

PostPosted: Sat Apr 28, 2007 1:52 pm     Reply with quote

Thank you PCM programmer.

I will get back with you on monday. (Because of the weekend)

I will post much simple codes. In fact i dont care about having and I2C mater with USB (it's already working) all i need is an I2C slave with USB. as you've mentioned i'll remove the USB code but i need to keep the USB configuration bits.

Thank you once again
PICoHolic



Joined: 04 Jan 2005
Posts: 224

View user's profile Send private message

PostPosted: Mon Apr 30, 2007 6:09 am     Reply with quote

here it is

Slave
Code:

#include <18F4550.h>
#device adc=8

#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN, NOPBADEN, ICPRT
#use delay(clock=48000000)

#use i2c(SLAVE, SDA=PIN_B0, SCL=PIN_B1, address=0xE0, FORCE_HW)

#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, errors)

#byte PORTA = 0xF80
#byte PORTB = 0xF81
#byte PORTC = 0xF82
#byte PORTD = 0xF83
#byte PORTE = 0xF84

#byte TRISE = 0xF96

#byte LATB = 0xF8A
#byte TRISB =0xF83

#byte SSPADD = 0xFC8
#byte SSPCON1 = 0xFC6

#byte SSPCON1  =  0xFC6
#bit  SSPOV    =  SSPCON1.6
///////////////////////////////////////////////////////////////////////////////
BYTE address, buffer[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8' };
//////////////////////////////////////////////////////////////////////////////
int8 States[32][2];
int8 statespointer = 0;
//////////////////////////////////////////////////////////////////////////////
#INT_SSP
void ssp_interupt()
{
   BYTE incoming, state;

   state = i2c_isr_state();
   states[statespointer++][0] = state;
   states[statespointer-1][1] = 0xAA;
   //putc(state);
   
   if(state < 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      //putc(incoming);
     
      states[statespointer++][0] = state;
      states[statespointer-1][1] = incoming;
     
      if(state == 1)                    //First received byte is address
      {
         address = incoming;
         //putc('a');
      }
      if(state == 2)                     //Second received byte is data
      {
         buffer[address] = incoming;
         //putc('d');
      }
   }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(buffer[address]);
      //putc('W');
   }
   
   SSPOV = 0;
}
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
void main()
{
   unsigned int8 Buff[16];
   unsigned int8 BuffPointer=0;
   int16 Val;
   int i;
   
   ////////// PROCESS ERRATA //////////////
   TRISB = 0x00;
   LATB =  0x00;
   TRISB = 0xFF;
   #ASM
      MOVF   0xFC9,W
      MOVFF  0x40,0xFC9
      BSF    0xFC6.4
      BCF    0xF9E.3
Lp:   BTFSC  0xFC7.0
      BRA    Lp
      MOVLW  0xE0
      MOVWF  SSPADD
      MOVLW  0x36
      MOVWF  SSPCON1
   #ENDASM
   /////////////////////////////
   
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   //setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
 
   //setup_low_volt_detect(FALSE);
   //setup_oscillator(False);
   //printf("Hello World\n\r");
   enable_interrupts(INT_SSP);
   clear_interrupt(INT_SSP);
   enable_interrupts(GLOBAL);
   
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
   while (1)
   {
      if (statespointer == 2)
      {
         disable_interrupts(INT_SSP);
         for (i=0;i<statespointer;i++)
            printf("\n\rState:%X  Incom:%X",states[i][0], states[i][1]);
         statespointer = 0;
         clear_interrupt(INT_SSP);
         enable_interrupts(INT_SSP);
      }
   }
}



Master
Code:

#include <18F4550.h>
#device adc=8

#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN, NOPBADEN, ICPRT
#use delay(clock=48000000)

#use i2c(Master, SDA=PIN_C0, SCL=PIN_C1, slow=100000)


#byte PORTA = 0xF80
#byte PORTB = 0xF81
#byte PORTC = 0xF82
#byte PORTD = 0xF83
#byte PORTE = 0xF84

#byte TRISE = 0xF96
void main()
{
   int8 i2cVal;
   
   set_tris_b(0x00);
   PORTB = 0xFF;
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
 
   //setup_low_volt_detect(FALSE);
   //setup_oscillator(False); 
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
   delay_ms(1000);
   output_low(PIN_B7);
   
   i2c_start();
   delay_ms(10);
   i2c_write(0xE0);
   delay_ms(10);
   i2c_write(0x00);
   delay_ms(10);
   i2c_write('A');
   delay_ms(10);
   i2c_stop();
   delay_ms(10);
   /*
   i2c_start();
   delay_ms(10);
   i2c_write(0xE1);
   i2cVal = i2c_read(0);
   delay_ms(10);
   i2c_stop();
   delay_ms(10);
   
   if (i2cVal == 0x30)
      output_high(PIN_B7);
   else
      output_low(PIN_B5);
   */
   
   output_high(PIN_B7);
   
   while (1)
   {
   
   }
   
}


The slave is responding to master writes. but the state value seems to be wrong. the output taken from hyperterminal shows:
State:00 Incom:AA
State:00 Incom:00
State:01 Incom:AA
State:01 Incom:41


State 2 never shows up!
right?

Also the slave is not responding to mater reads. The master stalls.

Thank you
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 30, 2007 12:11 pm     Reply with quote

Your master code to read a byte from the slave doesn't look correct.

See this post. This shows how to write a byte to the Ex_Slave.c code,
and how to read it back. You should do your 'read' code in the same
way:
http://www.ccsinfo.com/forum/viewtopic.php?t=28097&start=9
Then the read code should start working. (Change the i2c addresses
to the ones that you're using).

---------
Also, you have some code where you do a post-increment on an
array index and then in the next access, you subtract one from it.
Example:
Quote:

states[statespointer++][0] = 0x55;
states[statespointer-1][1] = 0xAA;

Suppose the index (statespointer) is initially 0. The 0x55 will be
written to states[0][0]. Then the index is incremented and becomes 1.
Then in your next access, you decrement it back to 0. The 0xAA is
written to states[0][1].

So your code is the same as the following:
Code:
states[statespointer][0] = 0x55;
states[statespointer][1] = 0xAA;

You don't need the "post-increment and then subtract 1" stuff.
It doesn't do anything.
PICoHolic



Joined: 04 Jan 2005
Posts: 224

View user's profile Send private message

PostPosted: Tue May 01, 2007 1:29 pm     Reply with quote

Thank you PCM Programmer
Quote:
Your master code to read a byte from the slave doesn't look correct.

it is correct. the read code is commented. i was just writing. If you take a look on the i2c code (master + USB) posted previously, it exactly matches your suggested code. And it was not working.
Code:

case 0xF4:                         //// I2C TEST ///////////
   i2c_start();
   i2c_write(0xE0);
   i2c_write(0x00);
   i2c_start();
   i2c_write(0xE1);
   i2cVal = i2c_read(0);
   i2c_stop();
   usb_cdc_putc(i2cVal);
 break;
 


Also

Quote:
Also, you have some code where you do a post-increment on an
array index and then in the next access, you subtract one from it.
Suppose the index (statespointer) is initially 0. The 0x55 will be
written to states[0][0]. Then the index is incremented and becomes 1.
Then in your next access, you decrement it back to 0. The 0xAA is
written to states[0][1].

This code is intented for troubleshooting and it's working as intended: states[i][0] has the state and states[i][1] has the incoming byte or 0xAA (used as a flag)
As a synthesis:
State:00 --> incoming: 00 (internal address)
State 01 --> incoming: 41 ('A' data)
I've been dealing with i2c master long time ago but it's my first time in i2c slave.
In i2c slave when state = 1 it means it's first byte, if state = 2 it means the 2nd. BUT when troubleshooting i found that state=0 is frst byte and so on...
Anyway the slave is responding to master writes but not to master reads.

Thank you.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 01, 2007 1:38 pm     Reply with quote

All I know is, make a test where the slave PIC is running the Ex_Slave.c
code. Then put the code from the following post into the Master PIC.
http://www.ccsinfo.com/forum/viewtopic.php?t=28097&start=9
Modify the #include, and #use statements so it's correct for your PICs.

That will prove if your Master-to-Slave hardware connections are correct
(including pull-up resistors on SDA and SCL, and a ground connection
between the two boards), and it will prove if your compiler version is
able to generate correct code for i2c Master and Slave.

You need to get down to basics and prove that everything works at a
low level, before you start adding your application code.
That's the reason for my suggestion of doing this test.
PICoHolic



Joined: 04 Jan 2005
Posts: 224

View user's profile Send private message

PostPosted: Wed May 02, 2007 3:41 am     Reply with quote

OK here it is:

Master:
Code:

#include <18F4550.h>
#device adc=8

#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN, NOPBADEN, ICPRT
#use delay(clock=48000000)

#use i2c(Master, SDA=PIN_C0, SCL=PIN_C1, slow=100000)
#byte PORTA = 0xF80
#byte PORTB = 0xF81
#byte PORTC = 0xF82
#byte PORTD = 0xF83
#byte PORTE = 0xF84
#byte TRISE = 0xF96
/////////////////////////////////////////////
void main()
{
   int8 i2cVal;
   
   set_tris_b(0x00);
   PORTB = 0xFF;
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
 
   //setup_low_volt_detect(FALSE);
   //setup_oscillator(False); 
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
   delay_ms(1000);
   output_low(PIN_B7);
   output_low(PIN_B5);
   
   // Write the letter 'B' to the slave board.
i2c_start();
i2c_write(0xE0);
i2c_write(0x00);
i2c_write('B');
i2c_stop();

// Read from the slave board and display the data.
i2c_start();
i2c_write(0xE0);
i2c_write(0x00);
i2c_start();
i2c_write(0xE1);
i2cVal = i2c_read(0);
i2c_stop();
   
   if (i2cVal == 'B')
      output_high(PIN_B5); //read value correct
   
   output_high(PIN_B7); // no stalls
   
   while (1)
   {
   
   }
   
}


Slave:
Code:

#include <18F4550.h>
#device adc=8

#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN, NOPBADEN, ICPRT
#use delay(clock=48000000)

#use i2c(SLAVE, SDA=PIN_B0, SCL=PIN_B1, address=0xE0, FORCE_HW)

#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, errors)

#byte PORTA = 0xF80
#byte PORTB = 0xF81
#byte PORTC = 0xF82
#byte PORTD = 0xF83
#byte PORTE = 0xF84
#byte TRISE = 0xF96
#byte LATB = 0xF8A
#byte TRISB =0xF83
#byte SSPADD = 0xFC8
#byte SSPCON1 = 0xFC6
#byte SSPCON1  =  0xFC6
#bit  SSPOV    =  SSPCON1.6
///////////////////////////////////////////////////////////////////////////////
BYTE address, buffer[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8' };
//////////////////////////////////////////////////////////////////////////////

#INT_SSP
void ssp_interupt()
{
   BYTE incoming, state;

   state = i2c_isr_state();

   if(state < 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
           
           
      if(state == 1)                    //First received byte is address
      {
         address = incoming;
      }
      if(state == 2)                     //Second received byte is data
      {
         buffer[address] = incoming;
      }
   }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(buffer[address]);
   }
   
   SSPOV = 0;
}
//////////////////////////////////////////////////////////
void main()
{
   unsigned int8 Buff[16];
   unsigned int8 BuffPointer=0;
   int16 Val;
   int i;
   
   ////////// PROCESS ERRATA //////////////
   TRISB = 0x00;
   LATB =  0x00;
   TRISB = 0xFF;
   #ASM
      MOVF   0xFC9,W
      MOVFF  0x40,0xFC9
      BSF    0xFC6.4
      BCF    0xF9E.3
Lp:   BTFSC  0xFC7.0
      BRA    Lp
      MOVLW  0xE0
      MOVWF  SSPADD
      MOVLW  0x36
      MOVWF  SSPCON1
   #ENDASM
   /////////////////////////////
   
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   //setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
 
   //setup_low_volt_detect(FALSE);
   //setup_oscillator(False);
   //printf("Hello World\n\r");
   enable_interrupts(INT_SSP);
   clear_interrupt(INT_SSP);
   enable_interrupts(GLOBAL);
   
//////////////////////////////////////////////////////////////
   while (1)
   {
   }



Common GND is present + 2 pullups on SDA & SCL
B7 and B5 remain low on the master side! Sad

PCM Programmer, thank you for your help once again. To make things easier, the slave is responding to master [writes] with an offset in the state variable i.e. first byte comes when state=0, 2nd byte comes when state=1 and so on. Also the slave address (E0/E1) is considered as incoming byte when a restart condition is initialted Shocked
Anyway, i'm not able to read from the slave yet.

Thank you
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 02, 2007 1:00 pm     Reply with quote

I've worked on it a little here. I setup two PicDem2-Plus boards --
the master with an 18F452 and the slave with an 18F4550.

I went through some testing, and changed the Slave to a 18F452 and
it worked OK with that setup. The problem is in the 18F4550 as a
Slave. (There may be a problem with it as a Master as well, but
I'm only testing it as a Slave currently).

I tested the Slave 18F4550 with both vs. 3.249 and 4.033 and it fails
on both. The failure mode is that the Master locks up during reading.
It never returns from the i2c code.

I'm running a straight 20 MHz crystal in HS mode. I'm not trying
anything fancy such as running a PLL at this moment. Also, I got rid
of most of your code. I'm using totally striped down test programs.

I also have the rev. A3 silicon on the 18F4550. There are erratas
on the i2c slave operation. I don't think your code fixed those erratas.
I'll have to look at it later, and see if I can add the work-around code.
Maybe then it will work.

If you need to get your project running in the meantime, I would ditch
the 18F4550's. Get something that works.
PICoHolic



Joined: 04 Jan 2005
Posts: 224

View user's profile Send private message

PostPosted: Thu May 03, 2007 12:18 am     Reply with quote

Thank you PCM Programmer. I appreciate it.

You're right there are erratas in the A3 revision. i tried to work around using the following code.
Code:

   TRISB = 0x00;
   LATB =  0x00;
   TRISB = 0xFF;
   #ASM
      MOVF   0xFC9,W
      MOVFF  0x40,0xFC9
      BSF    0xFC6.4
      BCF    0xF9E.3
Lp:   BTFSC  0xFC7.0
      BRA    Lp
      MOVLW  0xE0
      MOVWF  SSPADD
      MOVLW  0x36
      MOVWF  SSPCON1
   #ENDASM


in fact the first three ststements need to be placed before the i2c initialization, but i dont know how to do it since CCS is generating i2c init on power up!
It's not working as you just mentioned Sad

I'll keep trying and if there's really something wrong with the 18F4550 i think we should contact microchip to find a solution because it should work! right? I mean 18F4550 has i2c and USB and they should work (both or each alone)

Thank you anyway
PICoHolic



Joined: 04 Jan 2005
Posts: 224

View user's profile Send private message

PostPosted: Thu May 03, 2007 1:42 am     Reply with quote

Hello PCM Programmer

Finaaaaaaaalllllllyyyyyyy
It's working

Output
Code:


state = SSPSTAT & 0B00101101;

State      Incoming
09          E0   (expected)
29          00   (expected)
29          42 ('B')   (expected)
09          E0   (expected)
29          00   (expected)
0D          E1  (here is the unexpected state 0D it should be 0C !!)
2C          FF  (master reads)    (expected)


Thank you once again.
I feel better now! Very Happy
Tim Bobbins
Guest







final answer
PostPosted: Sun Sep 02, 2007 1:12 am     Reply with quote

Am I to understand that you got the I2C working by replacing:

state = i2c_isr_state () ;
with:
state = SSPSTAT & 0B00101101;

Can you please post your working code. I am having similar troubles. I have revision A1 of the 18F4420
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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