|
|
View previous topic :: View next topic |
Author |
Message |
akohlsmith
Joined: 25 Apr 2012 Posts: 26
|
PIC24FJ32GA002 I2C, cannot get library to work |
Posted: Wed Apr 25, 2012 9:45 pm |
|
|
I'm running Version 4.109 in MPLAB 8.84. I'm trying to do some simple I2C with I2C1 on a PIC24FJ32GA002 running at 8MHz.
My program is very simple, but the I2C lines do not move from their pulled-up high values. I've looked at both pins 17/18 and the alternate pins at 14/15. The UART transmit line does the correct thing, but I2C refuses to move.
I've tried FORCE_HW, FORCE_SW, I2C1 (instead of SDA=/SDL=)... nothing seems to work.
Any ideas?
Code: |
#include "24FJ32GA002.h"
#include <stdlib.h>
#include <stdio.h>
#fuses FRC,NOOSCIO,PROTECT,NODEBUG
#fuses WPRES128,WPOSTS16,I2C1SELD,OSCIO,NOIESO
#fuses NOWDT
#use delay(clock=8000000)
// PWM output
#pin_select OC2=PIN_B6
#pin_select OC3=PIN_B7
/* map i2c data/clock to a name */
#define PIN_I2C_SDA PIN_B9
#define PIN_I2C_SCL PIN_B8
#use rs232(baud=9600, xmit=PIN_A2, rcv=PIN_A4) // PIN_A4 Also to be used for Jumper J2
#use i2c(master, force_hw, slow, sda=PIN_I2C_SDA, scl=PIN_I2C_SCL)
#define HIH6130_ADDR (0x24)
#define SHT21_ADDR (0x40)
#define HIH6130_STATUS_MASK (0xc0)
#define I2C_RD (1)
#define I2C_WR (0)
#define I2C_ACK (1)
#define I2C_NAK (0)
/* raw data values, filled in by I2C routines */
long hih6130_raw_rh = 0;
long hih6130_raw_t = 0;
/* I2C Code */
/* send a measurement request. in ~40ms issue a data request */
void hih6130_request(void)
{
printf("---req\r\n");
i2c_start();
i2c_write(HIH6130_ADDR << 1 | I2C_WR);
i2c_stop();
}
/* send a data request; returns 1 if the status shows a valid measurement was received */
BOOLEAN hih6130_get_data(void)
{
unsigned char b1, b2, b3, b4;
long raw1, raw2;
printf("---dat: ");
i2c_start();
if (i2c_write(HIH6130_ADDR << 1 | I2C_RD)) { /* no ACK? */
printf("N\r\n");
return FALSE;
}
b1 = i2c_read(I2C_ACK);
b2 = i2c_read(I2C_ACK);
b3 = i2c_read(I2C_ACK);
b4 = i2c_read(I2C_NAK);
i2c_stop();
printf("%x %x %x %x\r\n", b1, b2, b3, b4);
if (b1 & HIH6130_STATUS_MASK) { /* if any status bits are set, data not ready */
return FALSE;
}
/* now take the raw I2C data and stuff it into the 16-bit holding registers */
raw1 = (b1 & ~HIH6130_STATUS_MASK) << 8;
raw1 |= b2;
raw2 = b3 << 8;
raw2 |= b4;
raw2 >>= 2;
hih6130_raw_rh = raw1;
hih6130_raw_t = raw2;
return TRUE;
}
void main(void)
{
output_float(PIN_I2C_SDA);
output_float(PIN_I2C_SCL);
while(1) {
hih6130_request();
delay_ms(50);
hih6130_get_data();
delay_ms(50);
printf("RH: %Ld, temp: %Ld\r\n", hih6130_raw_rh, hih6130_raw_t);
};
}
| [/code] |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Apr 26, 2012 5:37 am |
|
|
I don't see a problem in your code and am not aware of an issue with PCD V1.09. I see, that it's setting an I2C speed of only 25 kHz with your code, but that won't hurt. Are you sure that your hardware is O.K.?
If you have an early (A3/A4) chip version, it may be affected by I2C related silicon errata, see the respective MHCP errata sheet. |
|
|
akohlsmith
Joined: 25 Apr 2012 Posts: 26
|
|
Posted: Thu Apr 26, 2012 2:01 pm |
|
|
FvM wrote: | I see, that it's setting an I2C speed of only 25 kHz with your code |
Where do you see that? I thought "slow" was 100kHz. As you said though, that should not be presenting a problem, but I'm curious to know.
Quote: | Are you sure that your hardware is O.K.? |
I believe so. We're going to do a straight I/O wiggle test (no I2C) to make sure.
Quote: | If you have an early (A3/A4) chip version, it may be affected by I2C related silicon errata, see the respective MHCP errata sheet. |
How do I detect this programmatically? I am still trying to pick up PICCs method of accessing SFRs. I don't expect I can just set up an int pointer to DEVID? Harvard architectures have some peculiar addressing modes. :-) |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9224 Location: Greensville,Ontario
|
|
Posted: Thu Apr 26, 2012 3:20 pm |
|
|
Do you have the correct pullups on the I2C bus lines ? |
|
|
akohlsmith
Joined: 25 Apr 2012 Posts: 26
|
|
Posted: Thu Apr 26, 2012 4:41 pm |
|
|
temtronic wrote: | Do you have the correct pullups on the I2C bus lines ? |
Yes, 4.7k each to the 3.3V rail. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Apr 26, 2012 10:52 pm |
|
|
Quote: | My program is very simple, but the I2C lines do not move from their
pulled-up high values.
|
Your test program is too complicated, if all you want to do is check for
bus activity.
To check for activity on the i2c bus, first remove all external i2c slave
chips from the bus. But leave the pull-ups on it. Then run a test
program with a very simple loop that writes to the i2c bus. Look for
pulses on SDA and SCL with your oscilloscope. Example of a simple test:
Code: |
while(1)
{
i2c_write(0x55);
delay_us(500);
}
|
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Apr 26, 2012 11:29 pm |
|
|
Quote: | Where do you see that? I thought "slow" was 100kHz. |
In the I2C1BGR setup. It should be 0x9d for fcy of 4 MHz but is 0x27. It's apparently a PCD V4.109 bug that has been fixed in later versions. |
|
|
akohlsmith
Joined: 25 Apr 2012 Posts: 26
|
|
Posted: Thu Apr 26, 2012 11:49 pm |
|
|
Just an update -- I got it working. It seems that for some reason #USE STANDARD_IO(all) had to be declared, even though the docs say this is the default. FvM's right too; I've got a 40us clock period with the settings given. It's slow but fine for my application.
Thanks everyone for your assistance. It's truly appreciated. |
|
|
|
|
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
|