CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

i2c_transfer and PIC18F55Q43
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Wed Mar 31, 2021 2:22 am     Reply with quote

It gets interesting....

Just tried the experiment of building a basic project based upon your
original code:
Code:

#include "18F55Q43.h"
#device ADC=12

#FUSES NOWDT                    //No Watch Dog Timer

#use delay(crystal=20000000)
#pin_select U1TX=PIN_C5
#pin_select U1RX=PIN_C6
#use rs232(baud=9600,parity=N,UART1, bits=8,stream=PORT1)
#pin_select SDA1=PIN_C4
#pin_select SCL1=PIN_C3
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,force_hw)

#define SHT31_I2C_ADDRESS  0x44

#define LED_Y PIN_D6
int8 wdata[2] = {0x30,0xa2};

void main()
{
   while(TRUE)
   {
      output_low(LED_Y);
      i2c_transfer(SHT31_I2C_ADDRESS, wdata, sizeof(wdata)+1);
      output_high(LED_Y);       
      delay_ms(200); //pause
   }
}


Looking at the assembler generated, the compiler uses SPI2, not SPI1
for this. Doing this implies the standard port slew rate controls apply,
not the I2C specific ones. Looking at the assembler, it does add:
Code:

00EC:  BSF    012.3
00EE:  BSF    012.4

To the initialisation code, which correctly sets these bits as open drain.
However it does not appear to turn off the slew rate limiting on the pins.

So then tried adding:
set_slow_slew_c(0b11110011);

which should turn off slew rate limiting on these bits, The resulting
assembler correctly sets 0x413 to 0xF3, so the slew rate limitation should
then be off. With this done, all the register settings look right, but using
SSP2, not SSP1. I'd suspect the compiler is deliberately doing this to
avoid the complexity of two different sets of settings to control the SSP.

So try:
Code:

#include "18F55Q43.h"
#device ADC=12

#FUSES NOWDT                    //No Watch Dog Timer

#use delay(crystal=20000000)
//obviously with suitable clock settings for your system
#pin_select U1TX=PIN_C5
#pin_select U1RX=PIN_C6
#use rs232(baud=9600,parity=N,UART1, bits=8,stream=PORT1)
#pin_select SDA1=PIN_C4
#pin_select SCL1=PIN_C3
#use i2c(Master,Fast=400000,sda=PIN_C4,scl=PIN_C3,force_hw)

#define SHT31_I2C_ADDRESS  0x44

#define LED_Y PIN_D6
int8 wdata[2] = {0x30,0xa2};

void main()
{
   set_slow_slew_c(0b11110011);
   while(TRUE)
   {
      output_low(LED_Y);
      i2c_transfer(SHT31_I2C_ADDRESS, wdata, sizeof(wdata)+1);
      output_high(LED_Y); 
      delay_ms(200); //pause
   }
}

However there is then another issue. Instead of setting the SSP2BAUD
register to the correct value for 400K, it just clears bit 5 of this. Since the
default boot value in this register is '0', this results in the baud rate
being set to 5MHz (for my 20MHz clock). Ugh!.... This is why you are not
getting the right operation. Trying different speeds, it still does exactly
the same. Trying i2c_speed, the compiler complains!...
As you say it only changes operation for this when you use the
clock_source setting...
So it is getting some of the settings badly wrong for this.

Report this to CCS. It is giving very wrong settings... Sad
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Wed Mar 31, 2021 6:20 am     Reply with quote

In their data sheet Microchip uses ODCONx for this name as well so we can't blame CCS for it Smile

The i2c speed setting (fast=xxxxxx) indeed does nothing.

My best result is using the mfintosc as a clock source:

Code:

#use i2c(Master,I2C1,clock_source=mfintosc)


This 500KHz internal oscillator gives me a 100kHz i2c clock. Slow, but supported by the SHA31 and I need the 6 bytes of T and RH data only every now and then.

I am not sure if I fully understand your remark about SSP2; do you mean that the i2c module uses SSP2 to do its timing? Only I think this chip does not have an SSP. It has two SPI modules but afaics they are not used for clocking i2c.

i2c has its own clock selection register: I2CxCLK, 0x029C. Compiling the above mentioned #use I see:

0AEE: MOVLB 4
0AF0: BSF x12.3
0AF2: BSF x12.4
0AF4: BCF 4C8.3
0AF6: BCF 4C8.4
0AF8: MOVLW 03
0AFA: MOVLB 2
0AFC: MOVWF x9C

This sets C3 and C4 for open drain, TRISC.3 and TRISC.4 for output and sets I2CxCLK to 0x03, which selects mfoscint. Looks OK to me. Why that gives me a 100kHz i2c clock instead of 500kHz is not clear.

What I learn from this is that I do not need the separate
Code:

#byte ODCON=getenv("SFR:ODCONC")
bit_set(ODCON,3);
bit_set(ODCON,4);

after all; they are set by the #use statement.

There is definitely something not right with the compiler for the i2c module in this chip; now only how to explain that to CCS Confused
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Wed Mar 31, 2021 7:29 am     Reply with quote

Actually MicroChip are the problem on the name.
They use the different nomenclature on some other chips. This is what
makes it really 'fun'..... Sad

SSP, s 'synchronous serial port', as opposed to SPI as 'serial peripheral
interface'. The older chips all refer to this peripheral as the MSSP (master
synchronous serial port). Since the peripheral supports both doing SPI,
and I2C, calling it 'SPIx' slightly hides what it can do....

Yes, CCS are accessing the wrong peripheral (and giving it the wrong value), when setting up the baud rate. So you have lines like:
Code:

00FA:  BCF    SPI2BAUD.5
00FC:  BCF    SPI1STATUS.-
00FE:  BSF    SPI1STATUS.SPI1RXBF
0100:  BCF    SPI1CON2.TXR
0102:  BSF    SPI1CON2.RXR
0104:  MOVLW  SPI1CON0
0106:  MOVWF  SPI2STATUS

For the setup. It is accessing some registers in SPI1, and others in SPI2,
but the only baud setting is done to SPI2, not SPI1 (and is wrong
anyway...).

It is a real mess at the moment.
temtronic



Joined: 01 Jul 2010
Posts: 9097
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Mar 31, 2021 8:48 am     Reply with quote

sounds like time to go back to the PIC16C84 and PIC16C71 Rolling Eyes
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Wed Mar 31, 2021 9:15 am     Reply with quote

Neuuh,

It always takes a couple of sweaty days to get a new PIC. If the PIC itself is new, more so.

On the other hand, when (not if, I hope) this all gets sorted out and I get to know its 952 pages long data sheet (when did that become two reams of paper?) a bit better it is a nice chip with more pins and possibilities than I think I need in the near future.

I do hope that Microchip does not kill it off before its time because I promised myself that this was going to be the last PIC I was going to use before retirement. And early retirement is unfortunately not an option Very Happy
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Thu Apr 01, 2021 12:31 am     Reply with quote

Unfortunately, there is one 'killer' for using this chip.
Look at the SRAM read back erratum.
This makes this chip 'unusable' for a lot of applications. Only recovery a
power cycle!. You need to make sure you don't get the B0 version, or you
can't really be sure the RAM actually works... Sad
Thankfully, given there are three revisions after this, for a chip that is quite
new, this was presumably only on relatively 'prototype' revisions.
Check the numbers when ordering and make sure you don't get the B0
revision.
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Thu Apr 01, 2021 2:22 am     Reply with quote

Good point.

Maybe a silly question, but how do I read the revision from this chip?

I was expecting to be able to see this in the device programmer sw but no.

I then toyed with read-device_info but only got garbage. Using read_rom_memory got me the 'B' but nothing else.

Probably because I'm mixing bits and bytes...
temtronic



Joined: 01 Jul 2010
Posts: 9097
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Apr 01, 2021 5:02 am     Reply with quote

Is it 'sad' that I KNOW that the're 500 pages in a 'ream' ?? Confused

I stopped looking at new PICs....PIC18F46K22 has more 'stuff under the hood' , than I'll ever need. Kinda the Swiss Army Knife of micros !
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Thu Apr 01, 2021 5:17 am     Reply with quote

temtronic wrote:
Is it 'sad' that I KNOW that the're 500 pages in a 'ream' ?? Confused!


No, not at all. Just shows you're well-read. Better question is why this word takes up space in my (Dutch-speaking) brain....
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Mon Apr 05, 2021 5:49 am     Reply with quote

Then something else regarding the new i2c_transfer function in the compiler. (Yes, I am still wrestling with this.....)

After clearing away the clocking problem and getting to understand how the pin settings for slew, pullup and input thresholds work I was left with i2c_tansfer() mostly working but still hanging up my code every now and then.

This morning I got fed up and took out the scope again Connected SDA, SCL and a third input for triggering. The scope does i2c decoding so I set it for that. I then found that every i2c_transfer() gave me a transfer with 1 extra byte.

Turns out this byte comes from the "+1" in my

Code:
i2c_transfer_out(SHT31_I2C_ADDRESS, sensirion_cmd, sizeof(sensirion_cmd)+1);


statements.

Leaving the +1 in I transfers one byte extra (the byte next in memory to the "sensirion_cmd" array). Removing it gives me the right number of bytes transferred.

I got the "sizeof(x)+1" from reading a couple of examples here. Now I know that you guys are both smart and not prone to making mistakes so now I wonder: did something get changed in the compiler (5.103)? Did a change I made in the #use I2c statement cause this? Did something else change in the 18F55Q43? Or did the +1 get eighty-sixed somewhere and did I not read about it? Smile
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon Apr 05, 2021 6:57 am     Reply with quote

Could easily be.
The +1, came from the original implementation of the transfer function,
when new chips came out that didn't have the MSSP. When originally
launched, you had to give the extra count for the address byte, since
the transfer count was for the whole 'packet', which was address, then the
block of data. CCS may have revised it now....
The entry in the manual now shows it with this being the data after the
address. There were a number of fixes to i2c_transfer at about 5.092.
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Mon Apr 05, 2021 7:47 am     Reply with quote

It kept me off the street for a couple of days....

Anyway, I'm happy to report that with a little help from this forum and a little help from myself I seem to have got i2c working now Very Happy

Thanks everyone for your time!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 05, 2021 11:21 am     Reply with quote

Woody wrote:


How do I read the revision from this chip?


When your ICD programmer "connects" to the PIC, it reports the PIC's
silicon revision in the programmer's output window.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon Apr 05, 2021 11:24 am     Reply with quote

When the I2C transfer function 'launched', the count byte was the value
actually given directly to the hardware function. If you read the data
sheet, this has to be one greater than the count of bytes to send.
I'd suspect CCS have fixed this to make it more like the same transfer
function on other chips. Smile
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Tue Apr 06, 2021 2:17 am     Reply with quote

PCM programmer wrote:
Woody wrote:


How do I read the revision from this chip?


When your ICD programmer "connects" to the PIC, it reports the PIC's
silicon revision in the programmer's output window.


Hmmm. Something strange going on with the device programmer.

On the device page under "Target Chip' initially I do not see Device ID or Revision. The labels and fields are not there. I can program, run and but no Device ID or Revision show.

Then, if I (on the User page) press 'Test for chip' and then return to device I get both a Device ID and a revision. The device ID is 7400, which is correct for this chip, but the revision shows 00. That should either be B0,B1 or B2, or, more likely, A040, A042 or A043.

So I am none the wiser Sad
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
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