View previous topic :: View next topic |
Author |
Message |
bdeb
Joined: 05 Nov 2010 Posts: 42 Location: Sweden
|
[SOLVED] PinSwapping MSSP ports on 16LF18346 locks PB7 low |
Posted: Wed Aug 28, 2019 9:25 am |
|
|
uP: 16LF18346 @3.0V
Compiler: 5.075
IDE: MPLAB-X 5.15 + PicKit 3
Dear gurus,
Testing 16LF18346 I used a PCB with I2C slave on MSSP2 and I2C master on MSSP1.
According to errata this is not optimal (at least not above 3.0V), but before moving wires, I was curious to put pin_select to the test, and did as below:
Code: |
#pin_select SCL1IN=PIN_B7 //Default B6
#pin_select SCL1OUT=PIN_B7
#pin_select SDA1IN=PIN_B5 //Default B4
#pin_select SDA1OUT=PIN_B5
#pin_select SCL2IN=PIN_B6 //Default B7
#pin_select SCL2OUT=PIN_B6
#pin_select SDA2IN=PIN_B4 //Default B5
#pin_select SDA2OUT=PIN_B4
#use i2c(SLAVE, I2C1, FORCE_HW, ADDRESS=0x42, STREAM=I2CS)
#use i2c(MASTER, I2C2, FORCE_HW, FAST=200000, STREAM=I2CM)
u8 I2CPtr;
u8 I2CBuf[30];
void Setup()
{
setup_adc_ports(sAN4|VSS_FVR); //sAN7 on B7 clearly not used + works if pin is MSSP1..
set_tris_b(0b11110000); //I2C pins set as input
clear_interrupt(INT_SSP);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
}
#INT_SSP
void IntI2C()
{
//Using stream "I2CS" because of dual I2C busses
u8 incoming;
u8 state;
u8 adr;
state = i2c_isr_state(I2CS);
if(state <= 0x80) //Master is writing
{
//Passing 2 as parameter, causes the function to read the SSPBUF without releasing the clock
if(state==0x80) { adr=i2c_read(I2CS,2); } //Our address (READ-mode)
else { incoming = i2c_read(I2CS); }
//if(state==0) { adr=incoming; } //Our address (WRITE-mode)
if(state==1) { I2CPtr=incoming; } //First received byte is "register address"
if(state>=2 && state!=0x80) //Next (0x02-0x7F) received byte is data
{
I2CBuf[I2CPtr++]=incoming;
}
}
if(state >= 0x80) //Master is reading (If 0x80 read above before write)
{
i2c_write(I2CS,I2CBuf[I2CPtr++]); //AutoIncrement+send from current address
}
}
|
I2C master (now on MSSP2) worked, but PB7 on slave was locked low.
Swapping back and instead re-soldering wires made it all work again.
I have changed coming PCB layout, so this is no problem - but I am very curious..
Apart from this I really love this PIC family - even more than 18F25K22.
UART Rx can wake us up from (deep) sleep..
Internal LP-oscillator makes external 32kHz Xtal redundant..
Pin swap like PIC24's..
Peripherals in abundance..
All the best:
/Björn
Last edited by bdeb on Thu Aug 29, 2019 4:20 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Aug 28, 2019 10:01 am |
|
|
I'm curious...
is this...
u8 I2CPtr;
legal in CCS C ?
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Wed Aug 28, 2019 10:22 am |
|
|
Some chips have an issue that they don't correctly release the clock.
Add this:
#bit CKP=getenv("BIT:CKP")
and then after the byte write in the slave code:
CKP=TRUE; |
|
|
bdeb
Joined: 05 Nov 2010 Posts: 42 Location: Sweden
|
|
Posted: Thu Aug 29, 2019 3:01 am |
|
|
Dear temtronic and Ttelmah, great tips as ususal!
Sorry for being unclear, I always use own defines, so
Code: |
#define u8 unsigned int8
|
should have been included. Sorry for that..
Seems there are actually two fixes:
But when testing my offending code, I actually used I2C-statements in *this* order:
Code: |
#use i2c(MASTER, I2C2, FORCE_HW, FAST=200000, STREAM=I2CM)
#use i2c(SLAVE, I2C1, FORCE_HW, ADDRESS=0x42, STREAM=I2CS)
|
Changing order so it reads like code in my post *also* makes it work - without CKP!
As I interpret the manual, this should actually make my slave code work even if *not* using stream "I2CS"
Oh well, it works and I have learned yet another thing!
All the best:
/Björn |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Thu Aug 29, 2019 3:29 am |
|
|
That is very interesting. Report it to CCS.
The order of #use's like this affect which one is seen as the 'default' (so
usable without a stream). It suggests that CCS's own CKP code is being
affected by which is the default stream.
Anyway, glad you have a fix. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Thu Aug 29, 2019 4:58 am |
|
|
NICE ! Something fixed in a day without hairloss !!
The #defines makes sense, and I like less typing.....can't spell, 1/2 dead finger and WHERE did the 'cents' sign key go ??
I'm wondering if CCS puts in more code for 'master' than 'slave' and the order kinda makes sense to me. |
|
|
bdeb
Joined: 05 Nov 2010 Posts: 42 Location: Sweden
|
|
Posted: Thu Aug 29, 2019 11:07 am |
|
|
Actually there is a third way..
After reporting this, I already got a nice long reply from CCS - seems I missed correct syntax when changing my code to using streams!
Correct I2C read should be:
Code: |
incoming = i2c_read(I2CS,1); //Oops, forgot the ",1" when converting to streams
|
Seems that my stream ID "I2CS" is interpreted as "2",
or "Read+ClockStretch" (on last defined #use i2c)
I will now sit silently in shame and count my remaining brain cells..
/Björn |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Thu Aug 29, 2019 11:52 am |
|
|
and (of course), swapping the declaration order swaps the numeric
value associated with the stream ID.
Aaargh!... |
|
|
|