|
|
View previous topic :: View next topic |
Author |
Message |
BrianC
Joined: 23 Apr 2022 Posts: 11 Location: UK
|
18F26K42 I2C [Solved] |
Posted: Sat Apr 23, 2022 8:30 am |
|
|
Hi,
I am trying to get the hardware I2C master working on the K42,
Code: |
#pin_select SDA1OUT=PIN_C4
#pin_select SDA1IN=PIN_C4
#pin_select SCL1OUT=PIN_C3
#pin_select SCL1IN=PIN_C3
#use delay(internal=32000000)
#use i2c(Master,Slow,I2C1,force_hw)
|
However when I run the code it then sits in a tight loop at the #use i2c statement at lines 180 / 182, having set a flag then waiting for it to clear.
Any suggestions would be well received !
Regards
BrianC
Code: |
.................... #use i2c(Master,Slow,I2C1,force_hw)
*
0014A: MOVLB 3D
0014C: BCF x76.4
0014E: BCF x78.7
00150: BSF x78.2
00152: MOVFFL 206,3FEA
00158: MOVFFL 205,3FE9
0015E: MOVLB 2
00160: BTFSS x04.0
00162: BRA 016A
00164: MOVLB 3D
00166: BSF x73.6
00168: MOVLB 2
0016A: BTFSC x04.0
0016C: BRA 0172
0016E: MOVLB 3D
00170: BCF x73.6
00172: MOVLB 3D
00174: MOVF x6C,W
00176: BZ 017E
00178: MOVFFL 3FEE,3D6B
0017E: BSF x73.5
00180: BTFSC x73.5
00182: BRA 0180
00184: BTFSC x76.4
00186: BRA 0198
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Sat Apr 23, 2022 8:51 am |
|
|
re:
Quote: | 00180: BTFSC x73.5
00182: BRA 0180
|
OK, so whatever bit 5 of SFR 73 is, it is always high, Until is 'Clears' ( goes low), it'll be there forever, which is what you're seeing.
Would have to get the datasheet to see what it is,as I don't use that PIC.
great ..downloaded the sheet...
looked at the SFRs.. can't find x73.......sigh....I suppose it's really 0xNN73, but no idea what NN really is.
Also, looks like that PIC has a 'real' I2C peripheral...so there may be something 'funny' going on ?
Do you have pullups on the I2C clk and data pins ??
more looking....
I 'think' that SFR might be 0x3D73, the I2C control register for device #0. If so, then it makes sense.
You USE wants I2C device #1, but the code wants device #0.
trying to help....
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sat Apr 23, 2022 9:56 am |
|
|
You _have_ got suitable pullups on the wires?.
It'll hang there if the lines aren't going high. 0x3D72, is I2c1CON0, and
this is the start bit. Setting it sends a start, and it drops when the start
has been sent.The hardware waits for BFRE to be set, before it'll
assert this bit. This requires both lines to be high.
Also, what commands are you using to drive this?. This chip has the
'new' I2C module instead of the MSSP. You should be using the
I2C_transfer command, not I2C_start / I2C_write etc.. |
|
|
BrianC
Joined: 23 Apr 2022 Posts: 11 Location: UK
|
18F26K42 I2C |
Posted: Sat Apr 23, 2022 10:28 am |
|
|
Yes, pull-ups are on the board. and the commands are 'transfer' rather than 'start' ..... 'stop'. The old MSSP struff has worked well for years on this product, but had to redesign for the customer as lead times on the current PIC are November and beyond ! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sat Apr 23, 2022 1:18 pm |
|
|
Can you physically test the lines are high?.
What compiler version?. |
|
|
BrianC
Joined: 23 Apr 2022 Posts: 11 Location: UK
|
18F26K42 I2C |
Posted: Sat Apr 23, 2022 4:24 pm |
|
|
Yes, they are both high. The compiler version is 5.107, updated it a couple of days a go to make sure I had the latest version.
The bit that bothers me is that this seems to be at the point where it is initialising the i2c, and has not actually got as far as trying to send a byte. I know it has done some processing before this as at start up it checks some data in e2 and if it fails it reloads default data, and restarts. That is all working fine.
It has not got as far as trying to send the initialisation codes to the LCD display sat on the end of the i2c. I have an i2c protocol analyser sat on the i2c and it does not see anything. So looks like it has a problem executing the #use i2c statement. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sun Apr 24, 2022 3:11 am |
|
|
Odd.
I have just tried a basic test with a 46K42 (same chip except in a larger
package), and a 24LC01 EEPROM.
It runs:
Code: |
#include "18F46K42.h"
#device ADC=12
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOMCLR
#use delay(internal=32000000)
#pin_select SDA1=PIN_C4
#pin_select SCL1=PIN_C3
#use i2c(Master,Slow=100000,I2C1,stream=I2C)
#pin_select U1TX=PIN_B0
#pin_select U1RX=PIN_B1
#use rs232(baud=9600,parity=N,bits=8,stream=PORT1)
//Basic code to access 2401 EEPROM
#define EEPROM_ADDRESS BYTE
#define EEPROM_SIZE 128
#define EEPROM_R 0xa0
#define NULL (void *)0
//test if EEPROM gives an acknowledge
BOOLEAN ext_eeprom_ready() {
int1 ack;
ack=i2c_transfer(I2C,EEPROM_R, NULL ,0);
return !ack;
}
//write a byte to the eeprom
void write_ext_eeprom(BYTE address, BYTE data) {
int to_send[2];
while(!ext_eeprom_ready())
;
to_send[0]=address;
to_send[1]=data; //setup data to send
i2c_transfer(I2C, EEPROM_R, to_send, 2);
}
//read a byte from EEPROM
BYTE read_ext_eeprom(BYTE address) {
BYTE data;
while(!ext_eeprom_ready())
;
i2c_transfer(I2C, EEPROM_R, &address, 1, &data,1);
return(data);
}
void main()
{
int1 write=TRUE;
int16 rval;
while(TRUE)
{
if (write)
{
write_ext_eeprom(0,0xAA);
write_ext_eeprom(1,0x55);
write=FALSE;
}
//Now read back
rval=make16(read_ext_eeprom(0), read_ext_eeprom(1));
fprintf (PORT1, "Value read is %lx\n",rval);
delay_ms(1000);
}
}
|
It is not working right, not reading the right value, but that may be
something like needing to turn the slew rate limitation off on the pins.
Will investigate later when I have time. However it does not hang where
you are describing.
What are you calling to 'initialise the I2c'?. The only initialisation is done
at the start of main, where it programs the pin select options, sets up the
TRIs etc. It does not call this routine. This is only called for an actual
transfer.
If it is arriving at this part of the code without a call to I2C_Transfer
actually occurring, then it says there is a flow problem in the code.
Something like an interrupt enabled without a handler, which could
result in a call to an invalid address. |
|
|
BrianC
Joined: 23 Apr 2022 Posts: 11 Location: UK
|
18F26K42 I2C |
Posted: Sun Apr 24, 2022 3:52 am |
|
|
Many thanks,
I will have a look at this and see where it gets me. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Sun Apr 24, 2022 5:22 am |
|
|
hmm, not something like USE I2C before the pin selects?
One of those 'we need to see your code' problems......
It'd be nice to see Mr. T's #USE I2C(...) assembler to compare. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sun Apr 24, 2022 7:07 am |
|
|
The thing that worries me, is he talks as if this is happening before any
actual I2C calls. It only calls this section when I do the transfer.
I'll post the assembler later. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sun Apr 24, 2022 8:09 am |
|
|
Assembler:
Code: |
.................... #use i2c(Master,Slow=100000,I2C1,stream=I2C)
*
00018: MOVLB 3D
0001A: BCF x76.4
0001C: BCF x78.7
0001E: BSF x78.2
00020: MOVFFL @I2C_TRANSFER_OUT_HW_2471.P1+1,FSR0H
00026: MOVFFL @I2C_TRANSFER_OUT_HW_2471.P1,FSR0L
0002C: BTFSC ??65535.0
0002E: BSF x73.6
00030: BTFSS ??65535.0
00032: BCF x73.6
00034: MOVF x6C,W
00036: BZ 003E
00038: MOVFFL POSTINC0,I2C1TXB
0003E: BSF x73.5
00040: BTFSC x73.5
00042: BRA 0040
00044: BTFSC x76.4
00046: BRA 0058
00048: BTFSS x78.5
0004A: BRA 0044
0004C: MOVF x6C,W
0004E: BZ 0058
00050: MOVFFL POSTINC0,I2C1TXB
00056: BRA 0044
00058: BTFSC ??65535.0
0005A: BRA 0062
0005C: BTFSC x77.5
0005E: BRA 0058
00060: BRA 0066
00062: BTFSS x73.3
00064: BRA 0062
00066: CLRF @01
00068: BTFSC x74.5
0006A: INCF @01,F
0006C: MOVLB 0
0006E: RETURN 0
|
|
|
|
BrianC
Joined: 23 Apr 2022 Posts: 11 Location: UK
|
18F26K42 I2C |
Posted: Sun Apr 24, 2022 10:50 am |
|
|
I have just compiled it with exactly the same #use line and get the following assembler. The first part replicates yours, but then there is a second part, if that gives you any clue ????
Compiler 5.107
.................... #use i2c(Master,Slow=100000,I2C1,stream=I2C)
*
00028: MOVLB 3D
0002A: BCF x76.4
0002C: BCF x78.7
0002E: BSF x78.2
00030: MOVFFL 0F,3FEA
00036: MOVFFL 0E,3FE9
0003C: BTFSC 0D.0
0003E: BSF x73.6
00040: BTFSS 0D.0
00042: BCF x73.6
00044: MOVF x6C,W
00046: BZ 004E
00048: MOVFFL 3FEE,3D6B
0004E: BSF x73.5
00050: BTFSC x73.5
00052: BRA 0050
00054: BTFSC x76.4
00056: BRA 0068
00058: BTFSS x78.5
0005A: BRA 0054
0005C: MOVF x6C,W
0005E: BZ 0068
00060: MOVFFL 3FEE,3D6B
00066: BRA 0054
00068: BTFSC 0D.0
0006A: BRA 0072
0006C: BTFSC x77.5
0006E: BRA 0068
00070: BRA 0076
00072: BTFSS x73.3
00074: BRA 0072
00076: CLRF 01
00078: BTFSC x74.5
0007A: INCF 01,F
0007C: MOVLB 0
0007E: GOTO 00EE (RETURN)
00082: MOVLB 3D
00084: BCF x76.4
00086: BCF x78.3
00088: BSF x78.2
0008A: BCF x74.6
0008C: BSF x74.7
0008E: MOVFFL 0F,3FEA
00094: MOVFFL 0E,3FE9
0009A: BSF x73.5
0009C: BTFSC x73.5
0009E: BRA 009C
000A0: BCF x73.6
000A2: BTFSC x76.4
000A4: BRA 00B6
000A6: BTFSS x78.0
000A8: BRA 00A2
000AA: MOVFFL 3D6A,3FEE
000B0: MOVF x6C,W
000B2: BZ 00B6
000B4: BRA 00A2
000B6: BTFSC x78.0
000B8: MOVFFL 3D6A,3FEE
000BE: BTFSC x77.5
000C0: BRA 00B6
000C2: CLRF 01
000C4: BTFSC x77.3
000C6: BRA 00CC
000C8: BTFSC x76.4
000CA: INCF 01,F
000CC: MOVLB 0
000CE: GOTO 0112 (RETURN) |
|
|
BrianC
Joined: 23 Apr 2022 Posts: 11 Location: UK
|
18F26K42 I2C |
Posted: Sun Apr 24, 2022 11:08 am |
|
|
In case it is silly error my part I have attached the source for the piece of test code that I have been using to get the i2c running. This part of the project was written 10 years ago using Microchip C18, so having to rewrite it all, so its been a while since visited this project.
Code: |
#include <18F26K42.h>
#device ADC=12
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
//#device ICD=TRUE
#use delay(internal=2000000)
#pin_select SDA1=PIN_C4
#pin_select SCL1=PIN_C3
#use i2c(Master,Slow=100000,I2C1,stream=I2C)
static int i2c_lcd_address = 0x7C; //device I2C LCD address
static char i2c_control = 0x00;
static char i2c_data =0x00;
//==========================================================================
void WRITE_CODE(int8 i2c_control,int8 i2c_data)
{
i2c_transfer(I2C,i2c_lcd_address,i2c_control,i2c_data,3);
}
//====================================================================
static void Initial_st7032()
{
WRITE_CODE(0x00,0x38);
delay_us(300);
WRITE_CODE(0x00,0x38);
delay_us(300);
WRITE_CODE(0x00,0x38);
delay_us(300);
WRITE_CODE(0x00,0x0c);
delay_us(300);
WRITE_CODE(0x00,0x01);
delay_us(300);
WRITE_CODE(0x00,0x39);
delay_us(300);
WRITE_CODE(0x00,0x14);
delay_us(300);
WRITE_CODE(0x00,0x76);
delay_us(300);
WRITE_CODE(0x00,0x5f);
delay_us(300);
WRITE_CODE(0x00,0x68);
delay_us(300);
WRITE_CODE(0x00,0x06); //Incement, no shift
delay_us(300);
WRITE_CODE(0x00,0x0C); //Display On, Cursor Off, Blink Off
delay_us(300);
//====================================
WRITE_CODE(0x00,0x06); //Incement, no shift
delay_us(300);
WRITE_CODE(0x00,0x0C); //Display On, Cursor Off, Blink Off
delay_us(300);
}
//-------------------------------------------------------------------------------------
static void Write_Line1(unsigned char Position)
{
WRITE_CODE(0x00,(0x80+Position)); //0x80
delay_us(30);
}
//-------------------------------------------------------------------------------------
static void Write_Line2(unsigned char Position)
{
WRITE_CODE(0x00,(0xC0+Position)); //0x80
delay_us(30);
}
//========================================================================
void putr4XLCD(char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
WRITE_CODE(0x40,*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}
//============================================================================
void Display_Select_Option(void)
{
printf(WRITE_CODE," Select Option ");
delay_ms(20);
Write_Line2(0x00);
delay_ms(20);
printf(WRITE_CODE,"Restart NewRun");
delay_ms(20);
}
//===========================================================================
void main()
{
Initial_st7032(); //LCD Initialisation
while(TRUE)
{
//TODO: User Code
DisplayAgain:
delay_ms(50);
Write_Line1(0x00);
Display_Select_Option();
delay_ms(1000);
Goto DisplayAgain;
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sun Apr 24, 2022 11:52 am |
|
|
When I2C_transfer was first launched, you had to give it the total
count, including the address byte. This was quickly revised, and the count
now is just the length of the data, not the address as well.
The function then expects to receive an address of an array of bytes
containing what is to be sent, not separate integers.
Then your count is larger than what you are asking it to send.
Look at how I transfer the bytes into an array, and then pass the
array to the function. Not two separate bytes.
You are giving it more values than it expects, so with the overload,
probably triggering a read as well. |
|
|
BrianC
Joined: 23 Apr 2022 Posts: 11 Location: UK
|
18F26K42 I2C |
Posted: Sun Apr 24, 2022 12:15 pm |
|
|
Point taken, but the reality is there is showing up on the i2c protocol analyser, not even a 'start' transition, so I doubt it is getting that far. When you run the code under debug it stops in a tight loop within the code for the #use statement. |
|
|
|
|
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
|