|
|
View previous topic :: View next topic |
Author |
Message |
jeremiah
Joined: 20 Jul 2010 Posts: 1353
|
I2C2 module on the PIC24FJ64GA004 not working. |
Posted: Tue Nov 30, 2010 9:53 am |
|
|
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: 1353
|
|
Posted: Tue Nov 30, 2010 9:57 am |
|
|
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
|
|
Posted: Tue Nov 30, 2010 2:52 pm |
|
|
What's your development Kit? Are you sure, that you connected the signals correctly? |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1353
|
|
Posted: Mon Dec 06, 2010 1:31 pm |
|
|
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
|
|
Posted: Mon Jul 04, 2011 2:26 am |
|
|
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
|
|
Posted: Mon Jul 04, 2011 2:54 am |
|
|
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: 1353
|
|
Posted: Fri Jul 08, 2011 8:07 am |
|
|
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
|
CONFIRMATION OF ABOVE |
Posted: Wed Dec 10, 2014 4:22 am |
|
|
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. |
|
|
|
|
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
|