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

I2C2 module on the PIC24FJ64GA004 not working.

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



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

I2C2 module on the PIC24FJ64GA004 not working.
PostPosted: Tue Nov 30, 2010 9:53 am     Reply with quote

EDIT: Forgot to mention that the compiler version I am using is 4.114

I put together a simple program because I was having trouble getting the 2nd I2C module to work with an EEPROM (or at all for that matter).

Some observations:
1. The LST file generated appears to use the correct registers for the 2nd module

2. I tested the same hardware and code using the I2C1 module and it works with the I2C1 module but not with the I2C2.

3. The status register sets the BCL bit upon failure

4. Putting a scope on the lines shows no changes in either SDA2 or SCL2...both stay high the entire time.

My first thought was that there might be something wrong with the pic. I contacted microchip and they said it worked on their dev board with their code. I can't really check that because I cannot install their compiler and I do not have a dev board available (various IT and purchasing restrictions).

I tried a few register changes suggested by microchip, but they didn't work (commented out in eeprom.c)

My guess is that I am not doing something correct with setting up the code in the compiler that is allowing some hardware to interfere with I2C2 operation that the microchip compiler doesn't, but again, I cannot verify what the microchip compiler does.

Any suggestions would be appreciated.

here is my code, divided up into files:

Device.h
Code:

/*******************************************************************************
*   Filename:  device.h
*   Desc.:     device.h contains definitions used for general PIC24
*              functionality.  This includes #device, #fuse, #use, and
*              #pin_select directives as well as header files used to work
*              with the PIC and compiler
*   History:   10/12/2010 - JHB - Creation
*
*******************************************************************************/
#ifndef DEVICE_H
#define DEVICE_H

//Include file that comes with the compiler
#include <24FJ64GA004.h>

//16 bit pointers
#device *=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOJTAG                   //JTAG disabled
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES ICSP1                    //ICD uses PGC1/PGD1 pins
#FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
#FUSES WINDIS                   //Watch Dog Timer in non-Window mode
#FUSES WDT128                   //Watch Dog Timer PreScalar 1:128
#FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
#FUSES NOIESO                     //Internal External Switch Over mode enabled
#FUSES PR                     //Pimary oscillaotr enabled
#FUSES NOCKSFSM                 //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOOSCIO                  //OSC2 is clock output
#FUSES HS
#FUSES I2C1SELD   

//Pin Selects for remappable pins
#pin_select U1TX = PIN_C7  //C1  //C7
#pin_select U1RX = PIN_C6  //B3  //C6

// #use statements for delays, rs232, and i2c
#use delay(clock=22118400)
#use i2c(stream=I2C2_STREAM,Master,I2C2,SLOW,FORCE_HW)
#use rs232(UART1,baud=9600,parity=N,bits=8,DISABLE_INTS)

// user defined register mapping
#include "pic24fj64ga004_regs.h"

#endif


eeprom.c
Code:

/*******************************************************************************
*   Filename:  slave.c
*   Desc.:     slave.c is the file containing the main() function for the P6C
*              program.
*   History:   10/12/2010 - JHB - Creation
*******************************************************************************/
#case

#include "device.h"
#include "eeprom/eeprom_24lc256.h"


///////////////////////////////////////////////////////////////////////////////
//  NAME:  main()
//  DESC:  This is the main entry for the program.  The PIC is setup and then
//         set to sleep.
//  IN:    NONE -- only globals are used
//  OUT:   NONE
///////////////////////////////////////////////////////////////////////////////
void main()

   BYTE value = 0xd2;
   
   //This line serves no function other than to remove an annoying warning.
   rs232_errors = 0; 
   
   //Turn off SPI, ADC, and unneccessary timers
   SPI1STAT = 0;
   SPI2STAT = 0;
   setup_wdt(WDT_OFF);
   setup_timer1(TMR_DISABLED);
   setup_timer2(TMR_DISABLED);
   setup_timer3(TMR_DISABLED);
   setup_timer4(TMR_DISABLED);
   setup_timer5(TMR_DISABLED);
   setup_adc(ADC_OFF);
   setup_vref(VREF_DISABLED);
   setup_comparator(NC_NC_NC_NC);
   
   
   //Turn off I2C general call
   I2C1_GCEN = 0;
   I2C2_GCEN = 0;

//!//Suggested by microchip
//!   TRISB = 0xFFFF;
//!   AD1PCFG = 0xFFFF;
//!   CMCON = 0x0000;
//!   I2C1CON = 0x0000;
   
   
   delay_ms(50);
   printf("\r\n#######################START#######################\r\n");
   
   delay_ms(5000);
   
   eep1_write(0,0x23);
   delay_ms(10);
   value = eep1_read(0);
   printf("READ:  %x\r\n",value);
   
   //go to sleep
   while (TRUE) {}

}

#include "eeprom/eeprom_24lc256.c"


eeprom_24lc256.h
Code:

/*******************************************************************************
* FILENAME:  eeprom_24aa512.h
* DESC:      This is the header file for the 24aa512 EEPROM driver.  It
*            provides the functionality needed to interact with a 24aa512
*
* REVISION:
*    2010/09/23 -- JHB -- Creation
*
*******************************************************************************/
#ifndef EEPROM_24LC256_H
#define EEPROM_24LC256_H

#define EEP1_I2C_ADDR 0xa0 //hardwired

//Macros for ease of use.  These are specified for each EEPROM on the I2C bus.
//There can be up to 8 eeproms on the I2C bus.
#define eep1_write(address,value)  eep_write(EEP1_I2C_ADDR,address,value)
#define eep1_read(address)         eep_read(EEP1_I2C_ADDR,address)

////////////////////////////////////////////////////////////////////////////////
// NAME:  eep_write()
// DESC:  This method writes a byte to the EEPROM with the specified I2C address
//        at the specified location in memory.
// IN:    i2c_address -- The EEPROM's I2C address
//        address     -- The location in EEPROM memory to write to
//        value       -- The value to write
// OUT:   NONE
////////////////////////////////////////////////////////////////////////////////
void eep_write(BYTE i2c_address, WORD address, BYTE value);

////////////////////////////////////////////////////////////////////////////////
// NAME:  eep_read()
// DESC:  This method reads a byte from the EEPROM with the specified I2C
//        address at the specified location in memory.
// IN:    i2c_address -- The EEPROM's I2C address
//        address     -- The location in EEPROM memory to read from
// OUT:   A byte consisting of the value at the specified EEPROM address
////////////////////////////////////////////////////////////////////////////////
BYTE eep_read(BYTE i2c_address, WORD address);

#endif


eeprom_24lc256.c
Code:

/*******************************************************************************
* FILENAME:  eeprom_24aa512.c
* DESC:      This is the definition file for the 24aa512 EEPROM driver.  It
*            provides the functionality needed to interact with a 24aa512
*
* REVISION:
*    2010/09/23 -- JHB -- Creation
*
*******************************************************************************/
#include "device.h"
#include "eeprom/eeprom_24lc256.h"

#define EEPROM_STREAM I2C2_STREAM

//Macros for ease of use
#define eep_i2c_start()      i2c_start(EEPROM_STREAM)
#define eep_i2c_stop()       i2c_stop(EEPROM_STREAM)
#define eep_i2c_write(value) i2c_write(EEPROM_STREAM,value)
#define eep_i2c_read(ack)    i2c_read(EEPROM_STREAM,ack)


////////////////////////////////////////////////////////////////////////////////
// NAME:  eep_write()
// DESC:  This method writes a byte to the EEPROM with the specified I2C address
//        at the specified location in memory.
// IN:    i2c_address -- The EEPROM's I2C address
//        address     -- The location in EEPROM memory to write to
//        value       -- The value to write
// OUT:   NONE
////////////////////////////////////////////////////////////////////////////////
void eep_write(BYTE i2c_address, WORD address, BYTE value){
   eep_i2c_start();
   eep_i2c_write(i2c_address);  //I2C address  with R/nW set to 0
   eep_i2c_write(address>>8);   //EEPROM memory address to write to
   eep_i2c_write(address);
   eep_i2c_write(value);        //value
   eep_i2c_stop();
}

////////////////////////////////////////////////////////////////////////////////
// NAME:  eep_read()
// DESC:  This method reads a byte from the EEPROM with the specified I2C
//        address at the specified location in memory.
// IN:    i2c_address -- The EEPROM's I2C address
//        address     -- The location in EEPROM memory to read from
// OUT:   A byte consisting of the value at the specified EEPROM address
////////////////////////////////////////////////////////////////////////////////
BYTE eep_read(BYTE i2c_address, WORD address){
   BYTE result = 0;
   eep_i2c_start();
   eep_i2c_write(i2c_address);          //I2C address  with R/nW set to 0
   eep_i2c_write(address>>8);           //EEPROM memory address to read
   eep_i2c_write(address);
   eep_i2c_start();                     //restart for read portion
   eep_i2c_write(i2c_address | 0x01);   //I2C address  with R/nW set to 1
   result = eep_i2c_read(0);            //read the byte
   eep_i2c_stop();
   return result;
}


LST file
Code:

CCS PCD C Compiler, Version 4.114, 93508626               30-Nov-10 10:39

               Filename: C:\Users\Jeremiah.Breeden\Desktop\p6c_eeprom\p6c_eeprom.lst

               ROM used: 1146 bytes (3%)
                         Largest free fragment is 42882
               RAM used: 131 (2%) at main() level
                         142 (2%) worst case
               Stack:    2 locations

*
0000:  GOTO    396
.................... /*******************************************************************************
.................... *   Filename:  slave.c
.................... *   Desc.:     slave.c is the file containing the main() function for the P6C
.................... *              program.
.................... *   History:   10/12/2010 - JHB - Creation
.................... *******************************************************************************/
.................... #case
.................... 
.................... #include "device.h"
.................... /*******************************************************************************
.................... *   Filename:  device.h
.................... *   Desc.:     device.h contains definitions used for general PIC24
.................... *              functionality.  This includes #device, #fuse, #use, and
.................... *              #pin_select directives as well as header files used to work
.................... *              with the PIC and compiler
.................... *   History:   10/12/2010 - JHB - Creation
.................... *
.................... *******************************************************************************/
.................... #ifndef DEVICE_H
.................... #define DEVICE_H
.................... 
.................... //Include file that comes with the compiler
.................... #include <24FJ64GA004.h>
.................... //////// Standard Header file for the PIC24FJ64GA004 device ////////////////
.................... #device PIC24FJ64GA004
.................... #list
.................... 
.................... 
.................... //16 bit pointers
.................... #device *=16
.................... 
.................... #FUSES NOWDT                    //No Watch Dog Timer
.................... #FUSES NOJTAG                   //JTAG disabled
.................... #FUSES NOPROTECT                //Code not protected from reading
.................... #FUSES NOWRT                    //Program memory not write protected
.................... #FUSES NODEBUG                  //No Debug mode for ICD
.................... #FUSES ICSP1                    //ICD uses PGC1/PGD1 pins
.................... #FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
.................... #FUSES WINDIS                   //Watch Dog Timer in non-Window mode
.................... #FUSES WDT128                   //Watch Dog Timer PreScalar 1:128
.................... #FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
.................... #FUSES NOIESO                     //Internal External Switch Over mode enabled
.................... #FUSES PR                     //Pimary oscillaotr enabled
.................... #FUSES NOCKSFSM                 //Clock Switching is disabled, fail Safe clock monitor is disabled
.................... #FUSES NOOSCIO                  //OSC2 is clock output
.................... #FUSES HS
.................... #FUSES I2C1SELD     
.................... 
.................... //Pin Selects for remappable pins
.................... #pin_select U1TX = PIN_C7  //C1  //C7
.................... #pin_select U1RX = PIN_C6  //B3  //C6
.................... 
.................... // #use statements for delays, rs232, and i2c
.................... #use delay(clock=22118400)
*
0262:  CP0     W0
0264:  BTSC.B  42.1
0266:  BRA     270
0268:  REPEAT  #2B2C
026A:  NOP     
026C:  DEC     W0,W0
026E:  BRA     262
0270:  RETURN 
.................... #use i2c(stream=I2C2_STREAM,Master,I2C2,SLOW,FORCE_HW)
0272:  MOV     #FFFF,W0
0274:  BTSS.B  218.3
0276:  BRA     282
0278:  BTSC.B  219.6
027A:  BRA     278
027C:  MOV     W1,212
027E:  BTSC.B  219.6
0280:  BRA     27E
0282:  MOV     #0,W0
0284:  BTSC.B  219.7
0286:  INC     W0,W0
0288:  RETURN 
*
02CE:  MOV     #FFFF,W0
02D0:  BTSS.B  218.3
02D2:  BRA     2F6
02D4:  MOV     216,W2
02D6:  AND     W2,#1F,W2
02D8:  BRA     NZ,2D4
02DA:  BSET.B  216.3
02DC:  BTSC    W1.0
02DE:  BCLR.B  216.5
02E0:  BTSS    W1.0
02E2:  BSET.B  216.5
02E4:  MOV     216,W2
02E6:  AND     W2,#1F,W2
02E8:  BRA     NZ,2E4
02EA:  BSET.B  216.4
02EC:  BTSS.B  218.1
02EE:  BRA     2EC
02F0:  MOV     210,W0
02F2:  BTSC.B  218.6
02F4:  BCLR.B  218.6
02F6:  RETURN 
.................... #use rs232(UART1,baud=9600,parity=N,bits=8,DISABLE_INTS)
.................... 
.................... // user defined register mapping
.................... #include "pic24fj64ga004_regs.h"
.................... /*******************************************************************************
.................... *   Filename:  pic24fj64ga004_regs.h
.................... *   Desc.:     This file contains variables mapped to various registers for
.................... *              this chip.
.................... *
.................... *   History:   10/12/2010 - JHB - Creation
.................... *
.................... *******************************************************************************/
.................... #ifndef PIC24FJ64GA004_REGS_H
.................... #define PIC24FJ64GA004_REGS_H
.................... 
.................... #list
.................... 
.................... #endif
.................... 
.................... 
.................... #endif
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... #include "eeprom/eeprom_24lc256.h"
.................... /*******************************************************************************
.................... * FILENAME:  eeprom_24aa512.h
.................... * DESC:      This is the header file for the 24aa512 EEPROM driver.  It
.................... *            provides the functionality needed to interact with a 24aa512
.................... * 
.................... * REVISION:
.................... *    2010/09/23 -- JHB -- Creation
.................... *
.................... *******************************************************************************/
.................... #ifndef EEPROM_24LC256_H
.................... #define EEPROM_24LC256_H
.................... 
.................... #define EEP1_I2C_ADDR 0xa0 //hardwired
.................... 
.................... //Macros for ease of use.  These are specified for each EEPROM on the I2C bus.
.................... //There can be up to 8 eeproms on the I2C bus.
.................... #define eep1_write(address,value)  eep_write(EEP1_I2C_ADDR,address,value)
.................... #define eep1_read(address)         eep_read(EEP1_I2C_ADDR,address)
.................... 
.................... ////////////////////////////////////////////////////////////////////////////////
.................... // NAME:  eep_write()
.................... // DESC:  This method writes a byte to the EEPROM with the specified I2C address
.................... //        at the specified location in memory.
.................... // IN:    i2c_address -- The EEPROM's I2C address
.................... //        address     -- The location in EEPROM memory to write to
.................... //        value       -- The value to write
.................... // OUT:   NONE
.................... ////////////////////////////////////////////////////////////////////////////////
.................... void eep_write(BYTE i2c_address, WORD address, BYTE value);
.................... 
.................... ////////////////////////////////////////////////////////////////////////////////
.................... // NAME:  eep_read()
.................... // DESC:  This method reads a byte from the EEPROM with the specified I2C 
.................... //        address at the specified location in memory.
.................... // IN:    i2c_address -- The EEPROM's I2C address
.................... //        address     -- The location in EEPROM memory to read from
.................... // OUT:   A byte consisting of the value at the specified EEPROM address
.................... ////////////////////////////////////////////////////////////////////////////////
.................... BYTE eep_read(BYTE i2c_address, WORD address);
.................... 
.................... #endif
.................... 
.................... 
.................... 
.................... ///////////////////////////////////////////////////////////////////////////////
.................... //  NAME:  main()
.................... //  DESC:  This is the main entry for the program.  The PIC is setup and then
.................... //         set to sleep.
.................... //  IN:    NONE -- only globals are used
.................... //  OUT:   NONE
.................... ///////////////////////////////////////////////////////////////////////////////
.................... void main()
.................... {   
*
0396:  BSET.B  81.7
0398:  MOV     #1F16,W0
039A:  MOV     W0,6A4
039C:  MOV     #300,W0
039E:  MOV     W0,6D6
03A0:  MOV     #46,W0
03A2:  MOV.B   W0L,742
03A4:  MOV     #57,W0
03A6:  MOV.B   W0L,742
03A8:  BSET.B  742.6
03AA:  BCLR.B  2CC.2
03AC:  BSET.B  217.7
03AE:  BSET.B  217.5
03B0:  BSET.B  216.6
03B2:  BCLR.B  217.3
03B4:  BSET.B  216.7
03B6:  BCLR.B  217.0
03B8:  BSET.B  217.1
03BA:  BCLR.B  217.2
03BC:  CLR     21A
03BE:  MOV.B   #6C,W0L
03C0:  MOV.B   W0L,214
03C2:  CLR     800
03C4:  MOV     #8000,W4
03C6:  MOV     W4,220
03C8:  MOV     #400,W4
03CA:  MOV     W4,222
03CC:  BCLR.B  220.3
03CE:  MOV     #47,W4
03D0:  MOV     W4,228
03D2:  SETM    32C
03D4:  MOV     #2780,W15
03D6:  MOV     #27FF,W0
03D8:  MOV     W0,20
03DA:  NOP     
03DC:  MOV.B   #D2,W0L
03DE:  MOV.B   W0L,802
....................    BYTE value = 0xd2;
....................     
....................    //This line serves no function other than to remove an annoying warning.
....................    rs232_errors = 0;   
03E0:  CLR     800
....................     
....................    //Turn off SPI, ADC, and unneccessary timers
....................    SPI1STAT = 0;
03E2:  CLR     240
....................    SPI2STAT = 0;
03E4:  CLR     260
....................    setup_wdt(WDT_OFF);
03E6:  BCLR.B  740.5
....................    setup_timer1(TMR_DISABLED);
03E8:  CLR     104
....................    setup_timer2(TMR_DISABLED);
03EA:  CLR     110
....................    setup_timer3(TMR_DISABLED);
03EC:  CLR     112
....................    setup_timer4(TMR_DISABLED);
03EE:  CLR     11E
....................    setup_timer5(TMR_DISABLED);
03F0:  CLR     120
....................    setup_adc(ADC_OFF);
03F2:  CLR     320
....................    setup_vref(VREF_DISABLED);
03F4:  CLR     632
....................    setup_comparator(NC_NC_NC_NC);
03F6:  CLR     630
....................     
....................     
....................    //Turn off I2C general call
....................    I2C1_GCEN = 0;
03F8:  BCLR.B  206.7
....................    I2C2_GCEN = 0;
03FA:  BCLR.B  216.7
.................... 
.................... //!//Suggested by microchip
.................... //!   TRISB = 0xFFFF;
.................... //!   AD1PCFG = 0xFFFF;
.................... //!   CMCON = 0x0000;
.................... //!   I2C1CON = 0x0000;
....................     
....................     
....................    delay_ms(50);
03FC:  MOV     #32,W0
03FE:  CALL    262
....................    printf("\r\n#######################START#######################\r\n");
0402:  MOV     #0,W1
0404:  MOV     W1,W0
0406:  CALL    200
040A:  INC     W1,W1
040C:  MOV     W1,[W15++]
040E:  BTSC.B  223.1
0410:  BRA     40E
0412:  MOV     W0,224
0414:  MOV     [--W15],W1
0416:  MOV     #36,W0
0418:  CPSGT   W1,W0
041A:  BRA     404
....................     
....................    delay_ms(5000);
041C:  MOV     #1388,W0
041E:  CALL    262
....................     
....................    eep1_write(0,0x23);
0422:  MOV.B   #A0,W0L
0424:  MOV.B   W0L,804
0426:  MOV.B   #23,W0L
0428:  MOV.B   W0L,805
042A:  CLR     806
042C:  CALL    28A
....................    delay_ms(10);
0430:  MOV     #A,W0
0432:  CALL    262
....................    value = eep1_read(0);
0436:  MOV.B   #A0,W0L
0438:  MOV.B   W0L,804
043A:  CLR     806
043C:  CALL    2F8
0440:  MOV.B   W0L,802
....................    printf("READ:  %x\r\n",value);
0442:  MOV     #0,W1
0444:  MOV     W1,W0
0446:  CALL    246
044A:  INC     W1,W1
044C:  MOV     W1,[W15++]
044E:  BTSC.B  223.1
0450:  BRA     44E
0452:  MOV     W0,224
0454:  MOV     [--W15],W1
0456:  MOV     #6,W0
0458:  CPSGT   W1,W0
045A:  BRA     444
045C:  MOV.B   802,W0L
045E:  CLR.B   1
0460:  MOV     #2702,W1
0462:  CALL    360
0466:  BTSC.B  223.1
0468:  BRA     466
046A:  MOV     #D,W4
046C:  MOV     W4,224
046E:  BTSC.B  223.1
0470:  BRA     46E
0472:  MOV     #A,W4
0474:  MOV     W4,224
....................     
....................    //go to sleep
....................    while (TRUE) {}
0476:  BRA     476
.................... 
.................... }
.................... 
.................... #include "eeprom/eeprom_24lc256.c"
.................... /*******************************************************************************
.................... * FILENAME:  eeprom_24aa512.c
.................... * DESC:      This is the definition file for the 24aa512 EEPROM driver.  It
.................... *            provides the functionality needed to interact with a 24aa512
.................... * 
.................... * REVISION:
.................... *    2010/09/23 -- JHB -- Creation
.................... *
.................... *******************************************************************************/
.................... #include "device.h"
.................... /*******************************************************************************
.................... *   Filename:  device.h
.................... *   Desc.:     device.h contains definitions used for general PIC24
.................... *              functionality.  This includes #device, #fuse, #use, and
.................... *              #pin_select directives as well as header files used to work
.................... *              with the PIC and compiler
.................... *   History:   10/12/2010 - JHB - Creation
.................... *
.................... *******************************************************************************/
.................... #ifndef DEVICE_H
.................... #define DEVICE_H
.................... 
.................... //Include file that comes with the compiler
.................... #include <24FJ64GA004.h>
.................... 
.................... //16 bit pointers
.................... #device *=16
.................... 
.................... #FUSES NOWDT                    //No Watch Dog Timer
.................... #FUSES NOJTAG                   //JTAG disabled
.................... #FUSES NOPROTECT                //Code not protected from reading
.................... #FUSES NOWRT                    //Program memory not write protected
.................... #FUSES NODEBUG                  //No Debug mode for ICD
.................... #FUSES ICSP1                    //ICD uses PGC1/PGD1 pins
.................... #FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
.................... #FUSES WINDIS                   //Watch Dog Timer in non-Window mode
.................... #FUSES WDT128                   //Watch Dog Timer PreScalar 1:128
.................... #FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
.................... #FUSES NOIESO                     //Internal External Switch Over mode enabled
.................... #FUSES PR                     //Pimary oscillaotr enabled
.................... #FUSES NOCKSFSM                 //Clock Switching is disabled, fail Safe clock monitor is disabled
.................... #FUSES NOOSCIO                  //OSC2 is clock output
.................... #FUSES HS
.................... #FUSES I2C1SELD     
.................... 
.................... //Pin Selects for remappable pins
.................... #pin_select U1TX = PIN_C7  //C1  //C7
.................... #pin_select U1RX = PIN_C6  //B3  //C6
.................... 
.................... // #use statements for delays, rs232, and i2c
.................... #use delay(clock=22118400)
.................... #use i2c(stream=I2C2_STREAM,Master,I2C2,SLOW,FORCE_HW)
.................... #use rs232(UART1,baud=9600,parity=N,bits=8,DISABLE_INTS)
.................... 
.................... // user defined register mapping
.................... #include "pic24fj64ga004_regs.h"
.................... 
.................... #endif
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... 
.................... #include "eeprom/eeprom_24lc256.h"
.................... /*******************************************************************************
.................... * FILENAME:  eeprom_24aa512.h
.................... * DESC:      This is the header file for the 24aa512 EEPROM driver.  It
.................... *            provides the functionality needed to interact with a 24aa512
.................... * 
.................... * REVISION:
.................... *    2010/09/23 -- JHB -- Creation
.................... *
.................... *******************************************************************************/
.................... #ifndef EEPROM_24LC256_H
.................... #define EEPROM_24LC256_H
.................... 
.................... #define EEP1_I2C_ADDR 0xa0 //hardwired
.................... 
.................... //Macros for ease of use.  These are specified for each EEPROM on the I2C bus.
.................... //There can be up to 8 eeproms on the I2C bus.
.................... #define eep1_write(address,value)  eep_write(EEP1_I2C_ADDR,address,value)
.................... #define eep1_read(address)         eep_read(EEP1_I2C_ADDR,address)
.................... 
.................... ////////////////////////////////////////////////////////////////////////////////
.................... // NAME:  eep_write()
.................... // DESC:  This method writes a byte to the EEPROM with the specified I2C address
.................... //        at the specified location in memory.
.................... // IN:    i2c_address -- The EEPROM's I2C address
.................... //        address     -- The location in EEPROM memory to write to
.................... //        value       -- The value to write
.................... // OUT:   NONE
.................... ////////////////////////////////////////////////////////////////////////////////
.................... void eep_write(BYTE i2c_address, WORD address, BYTE value);
.................... 
.................... ////////////////////////////////////////////////////////////////////////////////
.................... // NAME:  eep_read()
.................... // DESC:  This method reads a byte from the EEPROM with the specified I2C 
.................... //        address at the specified location in memory.
.................... // IN:    i2c_address -- The EEPROM's I2C address
.................... //        address     -- The location in EEPROM memory to read from
.................... // OUT:   A byte consisting of the value at the specified EEPROM address
.................... ////////////////////////////////////////////////////////////////////////////////
.................... BYTE eep_read(BYTE i2c_address, WORD address);
.................... 
.................... #endif
.................... 
.................... 
.................... #define EEPROM_STREAM I2C2_STREAM
.................... 
.................... //Macros for ease of use
.................... #define eep_i2c_start()      i2c_start(EEPROM_STREAM)
.................... #define eep_i2c_stop()       i2c_stop(EEPROM_STREAM)
.................... #define eep_i2c_write(value) i2c_write(EEPROM_STREAM,value)
.................... #define eep_i2c_read(ack)    i2c_read(EEPROM_STREAM,ack)
.................... 
.................... 
.................... ////////////////////////////////////////////////////////////////////////////////
.................... // NAME:  eep_write()
.................... // DESC:  This method writes a byte to the EEPROM with the specified I2C address
.................... //        at the specified location in memory.
.................... // IN:    i2c_address -- The EEPROM's I2C address
.................... //        address     -- The location in EEPROM memory to write to
.................... //        value       -- The value to write
.................... // OUT:   NONE
.................... ////////////////////////////////////////////////////////////////////////////////
.................... void eep_write(BYTE i2c_address, WORD address, BYTE value){
*
028A:  MOV     W5,[W15++]
....................    eep_i2c_start();
028C:  BTSS.B  218.3
028E:  BRA     298
0290:  BSET.B  216.1
0292:  BTSC.B  216.1
0294:  BRA     292
0296:  BRA     29E
0298:  BSET.B  216.0
029A:  BTSC.B  216.0
029C:  BRA     29A
*
0478:  PWRSAV  #0
....................    eep_i2c_write(i2c_address);  //I2C address  with R/nW set to 0
*
029E:  MOV     804,W1
02A0:  CALL    272
....................    eep_i2c_write(address>>8);   //EEPROM memory address to write to
02A4:  MOV.B   807,W0L
02A6:  MOV     W0,W5
02A8:  CLR.B   B
02AA:  MOV.B   W5L,W1L
02AC:  CALL    272
....................    eep_i2c_write(address);
02B0:  MOV     806,W1
02B2:  CALL    272
....................    eep_i2c_write(value);        //value
02B6:  MOV.B   805,W0L
02B8:  MOV     W0,W1
02BA:  CALL    272
....................    eep_i2c_stop();
02BE:  MOV     #1F,W0
02C0:  AND     216,W0
02C2:  BRA     NZ,2BE
02C4:  BSET.B  216.2
02C6:  BTSC.B  216.2
02C8:  BRA     2C6
.................... }
02CA:  MOV     [--W15],W5
02CC:  RETURN 
.................... 
.................... ////////////////////////////////////////////////////////////////////////////////
.................... // NAME:  eep_read()
.................... // DESC:  This method reads a byte from the EEPROM with the specified I2C 
.................... //        address at the specified location in memory.
.................... // IN:    i2c_address -- The EEPROM's I2C address
.................... //        address     -- The location in EEPROM memory to read from
.................... // OUT:   A byte consisting of the value at the specified EEPROM address
.................... ////////////////////////////////////////////////////////////////////////////////
.................... BYTE eep_read(BYTE i2c_address, WORD address){
*
02F8:  MOV     W5,[W15++]
02FA:  CLR.B   805
....................    BYTE result = 0;
....................    eep_i2c_start();
02FC:  BTSS.B  218.3
02FE:  BRA     308
0300:  BSET.B  216.1
0302:  BTSC.B  216.1
0304:  BRA     302
0306:  BRA     30E
0308:  BSET.B  216.0
030A:  BTSC.B  216.0
030C:  BRA     30A
....................    eep_i2c_write(i2c_address);          //I2C address  with R/nW set to 0
030E:  MOV     804,W1
0310:  CALL    272
....................    eep_i2c_write(address>>8);           //EEPROM memory address to read
0314:  MOV.B   807,W0L
0316:  MOV     W0,W5
0318:  CLR.B   B
031A:  MOV.B   W5L,W1L
031C:  CALL    272
....................    eep_i2c_write(address);
0320:  MOV     806,W1
0322:  CALL    272
....................    eep_i2c_start();                     //restart for read portion
0326:  BTSS.B  218.3
0328:  BRA     332
032A:  BSET.B  216.1
032C:  BTSC.B  216.1
032E:  BRA     32C
0330:  BRA     338
0332:  BSET.B  216.0
0334:  BTSC.B  216.0
0336:  BRA     334
....................    eep_i2c_write(i2c_address | 0x01);   //I2C address  with R/nW set to 1
0338:  MOV.B   804,W0L
033A:  IOR      W0,  #1,W5
033C:  MOV.B   W5L,W1L
033E:  CALL    272
....................    result = eep_i2c_read(0);            //read the byte
0342:  MOV     #0,W1
0344:  MOV     W1,[W15++]
0346:  MOV     [--W15],W1
0348:  CALL    2CE
034C:  MOV.B   W0L,805
....................    eep_i2c_stop();
034E:  MOV     #1F,W0
0350:  AND     216,W0
0352:  BRA     NZ,34E
0354:  BSET.B  216.2
0356:  BTSC.B  216.2
0358:  BRA     356
....................    return result;
035A:  MOV.B   805,W0L
.................... }
035C:  MOV     [--W15],W5
035E:  RETURN 
.................... 
.................... 

Configuration Fuses:
   Word  1L: 3F7F   WPOSTS16 WDT128 WINDIS NOWDT ICSP1 NODEBUG NOWRT NOPROTECT NOJTAG
          H: 0000 
   Word  2L: 7AA6   HS I2C1SELD NOIOL1WAY NOOSCIO NOCKSFSM PR SOSC_SEC WUT_DEFAULT NOIESO
          H: 0000 


Last edited by jeremiah on Tue Nov 30, 2010 10:08 am; edited 1 time in total
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Tue Nov 30, 2010 9:57 am     Reply with quote

As an added note, simply changing the I2C2 option to the use statement to I2C1 and running jumper wires over to the eeprom from the I2C1 pins works fine. I get the appropriate output of 0x23.

This confirms to me that both the hardware setup and the eeprom drivers I wrote work.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Nov 30, 2010 2:52 pm     Reply with quote

What's your development Kit? Are you sure, that you connected the signals correctly?
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Mon Dec 06, 2010 1:31 pm     Reply with quote

Sorry for the late reply. Been having computer network problems at work.

This is not on a development board. It is on a homebrew board but I am very certain the hardware is correct. I was able to jumper I2C1 pins over to the same EEPROM and change the CCS #use i2c statement to use I2C1 and it works perfectly. The hardware configuration on the EEPROM is one we have been using for years (just with I2C1 only until now).

The pins on the PIC are correct. We use Pin1 and Pin44 for I2C1 and Pin23 and Pin24 for I2C2 (44 pin package). I triple checked to make sure SDA and SCL were appropriately connected.

Some further tests:
Changing the #use i2c statement to have FORCE_SW makes I2C2 work.
DdeVilliers



Joined: 04 Jul 2011
Posts: 1
Location: South Africa

View user's profile Send private message

PostPosted: Mon Jul 04, 2011 2:26 am     Reply with quote

Hi Jeremiah

We are experiencing the exact same issue on the PIC24FJ32GA004 with CCS version 4.114.

Works perfectly in master and slave mode on I2C1(pins 1 and 44) but nothing on I2C2(pins 23 and 24). Inspecting the PIC data sheet its two independent I2C channels and shouldn't be a problem running both.

Everything is connected correctly but SDA and SCL lines on I2C2 just stays high.

Really stuck this side. Have you managed to resolve the problem?
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Jul 04, 2011 2:54 am     Reply with quote

The Microchip Silicon Errata describes an issue with bitset operations to I2CxSTAT affecting chip revisions A3 and A4.
http://ww1.microchip.com/downloads/en/DeviceDoc/80470e.pdf

Generally, MPLAB hardware debugging is the way to trace the problem.

I suspect that the I2C2 pins have been set as analog inputs in your design. Check if the analog inputs are set to digital like in the above shown assembly listing:
Code:
03D2:  SETM    32C  ; AD1PCF = 0xFFFF all IOs to digital
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Fri Jul 08, 2011 8:07 am     Reply with quote

That may have been what caused it. Unfortunately, the project has already been released, so I can't go back and check, but that sounds pretty plausible.

@DdeVilliers:
We worked around it by adding FORCE_SW to the #use i2c() directive. I would try what FvM suggested first.
seems_plausible



Joined: 10 Dec 2014
Posts: 1

View user's profile Send private message

CONFIRMATION OF ABOVE
PostPosted: Wed Dec 10, 2014 4:22 am     Reply with quote

Sorry to necropost, however I just wanted to confirm that FvM's suggestion of making sure the port pins are configured for digital instead of analog worked for me.

This shouldn't have been a problem since the datasheet specified the ports would be configured automatically upon enabling the i2c module, however apparently one still needs to configure themselves.
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