View previous topic :: View next topic |
Author |
Message |
mjollymore
Joined: 17 Sep 2007 Posts: 6
|
DSPIC30f5016 I2C communications |
Posted: Mon Aug 24, 2009 9:03 pm |
|
|
I am attempting to bring up the I2C port on my DSPIC30F5016 design to communicate with an MCP23017. I have written the following app and am not getting any level changes on the SCL and SDA lines (I am using a TEK TDS2004B DSO to monitor). I have checked my pullup resistors (4.7k) are ok and have proven the pins (G2 and G3) have good electrical connections by toggling through output_high(), output_float(), and output_low() functions on each of these pins. Any help is appreciated. Here is the test code which is intended to simply start the process of initializing the MCP23017:
Code: |
#include <30F5016.h>
#DEVICE ICD=TRUE
#FUSES NOWDT //No Watch Dog Timer
//#FUSES FRC
#FUSES FRC_PLL4 //Internal Fast RC oscillator with 4X PLL
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES WPSB16 //Watch Dog Timer PreScalar B 1:16
#FUSES WPSA512 //Watch Dog Timer PreScalar A 1:512
#FUSES PUT64 //Power On Reset Timer value 64ms
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV47 //Brownout reset at 4.7V
#FUSES LPOL_HIGH //Low-Side Transistors Polarity is Active-High (PWM 0,2,4 and 6)
//PWM module low side output pins have active high output polar
#FUSES HPOL_HIGH //High-Side Transistors Polarity is Active-High (PWM 1,3,5 and 7)
//PWM module high side output pins have active high output polarity
#FUSES PWMPIN //PWM outputs disabled upon Reset
#FUSES MCLR //Master Clear pin enabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES DEBUG //Debug mode for use with ICD
#FUSES NOCOE //Device will reset into operational mode
#FUSES ICSP1 //ICD uses PGC1/PGD1 pins
#FUSES RESERVED //Used to set the reserved FUSE bits
#use delay(clock=29480000)
#use I2C(master, SLOW, FORCE_HW, SCL=PIN_G2, SDA=PIN_G3)
/**********************************************************
I2C Defines
/*********************************************************/
#define Device_SDA PIN_G3
#define Device_SCL PIN_G2
/**********************************************************
System LED Definitions
**********************************************************/
#define Master_Indicator_Green PIN_F0
#define Master_Indicator_Red PIN_F1
/**********************************************************
MCP23017.h
#defines are with IOCON.BANK = 0
***********************************************************/
#define IODIRA 0x00
#define IODIRB 0x01
#define IPOLA 0x02
#define IPOLB 0x03
#define GPINTENA 0x04
#define GPINTENB 0x05
#define DEFVALA 0x06
#define DEFVALB 0x07
#define INTCONA 0x08
#define INTCONB 0x09
#define IOCONA 0x0A
#define IOCONB 0x0B
#define GPPUA 0x0C
#define GPPUB 0x0D
#define INTFA 0x0E
#define INTFB 0x0F
#define INTCAPA 0x010
#define INTCAPB 0x011
#define GPIOA 0x012
#define GPIOB 0x013
#define OLATA 0x014
#define OLATB 0x015
void main()
{
output_high (Master_Indicator_Green);
delay_ms (2000);
output_float (Master_Indicator_Green);
delay_ms (2000);
output_float (Master_Indicator_Red);
delay_ms (2000);
output_low (Master_Indicator_Red);
delay_ms (2000);
output_float (Master_Indicator_Red);
//Set up MCP
i2c_start(); //Issue Start condition on I2C
delay_us(20);
i2c_write(0x40); //MCP23017 Control Byte to set up write
// -------------------------------------------------
// |Bit7 |Bit6 |Bit5 |Bit4 |Bit3 |Bit2 |Bit1 |Bit0 |
// |0 |1 |0 |0 |A2 |A1 |A0 |R/W |
// |0 |1 |0 |0 |0 |0 |0 |0 |
// -------------------------------------------------
delay_us(20);
i2c_write(IODIRA); //Select the register to write to
delay_us(20);
i2c_write(0xF8); //Write data to that register
delay_us(20);
i2c_stop(); //Issue Stop condition on I2C
delay_us(50);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Aug 25, 2009 9:09 am |
|
|
I2C seems to work in most recent PCD version V4.097. What's your version? |
|
![](templates/subSilver/images/spacer.gif) |
mjollymore
Joined: 17 Sep 2007 Posts: 6
|
|
Posted: Tue Aug 25, 2009 11:16 am |
|
|
Hello FvM
I am running PCWHD PCD v4.093...am I correct in inferring that I2C was less than stable in versions prior to v4.097?
In any event I'll upgrade and try it.
Thanks. Mark |
|
![](templates/subSilver/images/spacer.gif) |
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Aug 25, 2009 2:41 pm |
|
|
I didn't yet use I2C with PIC24 or dsPIC33. I reviewed the assembly code and it seemed correct. But I don't see relevant changes since V4.093. So it may be the case, that there's still an I2C problem with PCD V4.097, but I didn't realize it. |
|
![](templates/subSilver/images/spacer.gif) |
armondo52 Guest
|
I2c |
Posted: Tue Sep 01, 2009 1:56 pm |
|
|
I am using it on a dsPic30F6015. I had a problem using it on a Microchip port expander. My solution was to set it to slow and its been working correctly ever since. I believe it has something to do with lead lengths and noise.
good luck |
|
![](templates/subSilver/images/spacer.gif) |
mjollymore
Joined: 17 Sep 2007 Posts: 6
|
I2C |
Posted: Tue Sep 01, 2009 3:20 pm |
|
|
Hi Armondo52
Thanks for the tip. I've been on vacation for awhile but am back and tonight will be trying the new version of the compiler to see if it sorts things out. I have the I2C set to SLOW:
Code: |
#use I2C(master, SLOW, FORCE_HW, SCL=PIN_G2, SDA=PIN_G3) |
and am not seeing any level changes on the I2C lines using a scope, so likely somewhere there is a botched piece of code. I have a few things to to try and will post any lessons-learned/code once I figure this out.
Thanks again. MJ |
|
![](templates/subSilver/images/spacer.gif) |
mjollymore
Joined: 17 Sep 2007 Posts: 6
|
|
Posted: Wed Sep 02, 2009 10:31 am |
|
|
I installed V4.098 last night, recompiled and ran. No change in the I2C performance....that is to say there isn't any level changes happening on the I2C lines. Any help will be appreciated.
Thanks, MJ |
|
![](templates/subSilver/images/spacer.gif) |
bkamen
Joined: 07 Jan 2004 Posts: 1611 Location: Central Illinois, USA
|
|
Posted: Thu Sep 03, 2009 4:02 pm |
|
|
Consider sending the LST code to support -- OR more importantly, shrink your code down to minimal size so I can run it too. I have a 16bit explorer demo board and the latest PCD (4.099) too.
So I can test it for you and look with my scope. (Agilent MSO6054a w/I2C decode)
-Ben
EDIT: nevermind: your code is pretty shrunk. Let me copy and work on it. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
![](templates/subSilver/images/spacer.gif) |
bkamen
Joined: 07 Jan 2004 Posts: 1611 Location: Central Illinois, USA
|
|
Posted: Thu Sep 03, 2009 4:08 pm |
|
|
BTW,
For the 30F5016, there doesn't seems to be a #fuse for BORV47
The compiler bails on that...
-ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
![](templates/subSilver/images/spacer.gif) |
mjollymore
Joined: 17 Sep 2007 Posts: 6
|
|
Posted: Thu Sep 03, 2009 6:16 pm |
|
|
Hello Ben,
Thanks very much for trying this out. I sent off my information to CCS Support on Tuesday and have had a couple of pings back to me re: compiler versions, etc so they are moving on it.
Last night in the wee hours I became a little concerned about the brown-out voltage I had set because I do have current limits set on my supply (which might be causing BOR in some instance), but I have had no problems compiling and running code fragments that exercise to ADC (to monitor a couple of fan speed set pots) and Capture modules (to determine the temperature via a thermistor) using the BORV fuse. As well the heartbeat LED that I run at the first of the I2C code fragment seem to me to indicate that things are in pretty good shape as I enter the I2C routines...but most everything is in question when it comes to my puzzle with the I2C.
I'll post any conclusions reached with CCS and any code I get running.
BTW: Wicked nice scope you have. My Tek and Cleverscope (for SPI and I2C decode) work ok, but an MSO (nevermind one of the calibre of an MSO6054a) would be mighty handy and clean up the clutter. -Insert sigh of envy here -
Thanks again and let me know if you have any other insights.
MJ |
|
![](templates/subSilver/images/spacer.gif) |
bkamen
Joined: 07 Jan 2004 Posts: 1611 Location: Central Illinois, USA
|
|
Posted: Thu Sep 03, 2009 10:18 pm |
|
|
As I mentioned, I an Explorer16 with a PIC33FJ256GP710 onboard. I added 4.7K resistors to +3.3V and viola.
Here's my code (I change things a little bit) but you can see the minor diff's...
and it works.
Code: | #define HPC16
#ifdef HPC16
#include <33FJ256GP710.h>
#DEVICE ICD=TRUE
#use delay(clock=8M)
#FUSES NOWDT //No Watch Dog Timer
//#FUSES FRC
#FUSES HS //Internal Fast RC oscillator with 4X PLL
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOWDT
#FUSES PUT128 //Power On Reset Timer value 64ms
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES DEBUG //Debug mode for use with ICD
#FUSES NOCOE,NOOSCIO,NOIESO
#FUSES ICSP1 //ICD uses PGC1/PGD1 pins
#FUSES RESERVED //Used to set the reserved FUSE bits
#FUSES NOJTAG
#use I2C(I2C1, master, FAST=1000000, FORCE_HW)
#else
#include <30F5016.h>
#DEVICE ICD=TRUE
#FUSES NOWDT //No Watch Dog Timer
//#FUSES FRC
#FUSES FRC_PLL4 //Internal Fast RC oscillator with 4X PLL
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES WPSB16 //Watch Dog Timer PreScalar B 1:16
#FUSES WPSA512 //Watch Dog Timer PreScalar A 1:512
#FUSES PUT64 //Power On Reset Timer value 64ms
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV42 //Brownout reset at 4.7V
#FUSES LPOL_HIGH //Low-Side Transistors Polarity is Active-High (PWM 0,2,4 and 6)
//PWM module low side output pins have active high output polar
#FUSES HPOL_HIGH //High-Side Transistors Polarity is Active-High (PWM 1,3,5 and 7)
//PWM module high side output pins have active high output polarity
#FUSES PWMPIN //PWM outputs disabled upon Reset
#FUSES MCLR //Master Clear pin enabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES DEBUG //Debug mode for use with ICD
#FUSES NOCOE //Device will reset into operational mode
#FUSES ICSP1 //ICD uses PGC1/PGD1 pins
#FUSES RESERVED //Used to set the reserved FUSE bits
#use delay(clock=29480000)
#use I2C(master, SLOW, FORCE_HW, SCL=PIN_G2, SDA=PIN_G3)
#endif
/**********************************************************
I2C Defines
/*********************************************************/
#ifdef HPC16
#else
#define Device_SDA PIN_G3
#define Device_SCL PIN_G2
#endif
/**********************************************************
System LED Definitions
**********************************************************/
#ifdef HPC16
#define Master_Indicator_Green PIN_A7
#define Master_Indicator_Red PIN_A6
#else
#define Master_Indicator_Green PIN_F0
#define Master_Indicator_Red PIN_F1
#endif
/**********************************************************
MCP23017.h
#defines are with IOCON.BANK = 0
***********************************************************/
#define IODIRA 0x00
#define IODIRB 0x01
#define IPOLA 0x02
#define IPOLB 0x03
#define GPINTENA 0x04
#define GPINTENB 0x05
#define DEFVALA 0x06
#define DEFVALB 0x07
#define INTCONA 0x08
#define INTCONB 0x09
#define IOCONA 0x0A
#define IOCONB 0x0B
#define GPPUA 0x0C
#define GPPUB 0x0D
#define INTFA 0x0E
#define INTFB 0x0F
#define INTCAPA 0x010
#define INTCAPB 0x011
#define GPIOA 0x012
#define GPIOB 0x013
#define OLATA 0x014
#define OLATB 0x015
void main () {
while (true) {
output_high (Master_Indicator_Green);
delay_ms (1000);
output_float (Master_Indicator_Green);
delay_ms (1000);
output_high (Master_Indicator_Red);
delay_ms (1000);
output_float (Master_Indicator_Red);
//Set up MCP
i2c_start(); //Issue Start condition on I2C
delay_us(20);
i2c_write(0x40); //MCP23017 Control Byte to set up write
// -------------------------------------------------
// |Bit7 |Bit6 |Bit5 |Bit4 |Bit3 |Bit2 |Bit1 |Bit0 |
// |0 |1 |0 |0 |A2 |A1 |A0 |R/W |
// |0 |1 |0 |0 |0 |0 |0 |0 |
// -------------------------------------------------
delay_us(20);
i2c_write(IODIRA); //Select the register to write to
delay_us(20);
i2c_write(0xF8); //Write data to that register
delay_us(20);
i2c_stop(); //Issue Stop condition on I2C
delay_us(50);
}
}
|
As for the speed thing, I was tweaking the settings to get FAST = 400KHz (the image doesn't match)....
But without fiddling deeper, you can see the results...
![](http://www.benjammin.net/~bkamen/images/I2C-Test.png) _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
![](templates/subSilver/images/spacer.gif) |
mjollymore
Joined: 17 Sep 2007 Posts: 6
|
|
Posted: Fri Sep 04, 2009 11:45 am |
|
|
Thanks Ben. This helps. This weekend I'll take a look at the state of the relevant SFRs and tweak my code to match yours more closely and see what happens. |
|
![](templates/subSilver/images/spacer.gif) |
|