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

CCS Compiling problems with i2c

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Rigolon



Joined: 11 Nov 2022
Posts: 3

View user's profile Send private message

CCS Compiling problems with i2c
PostPosted: Fri Nov 11, 2022 11:19 am     Reply with quote

Hi guys, first post here.

I tried to find a solution, but I haven't got far.

I have a project that uses PIC18F452 and PCF8563 for RTC.
The thing is I made some small changes and when I tried to run my uC froze. I discovered the problem was with the RTC_init() function. After commenting this function my program runs normally (without RTC).

Code:

#ifndef __PCF8563_C__
#define __PCF8563_C__

#ifndef PIN_RTC_SDA
 #define PIN_RTC_SDA PIN_C4
 #define PIN_RTC_SCL PIN_c3
#endif

#use i2c(MASTER, sda=PIN_RTC_SDA, scl=PIN_RTC_SCL, stream=STREAM_PCF8563)

typedef struct
{
   unsigned int8 year;  //years since 2000
   unsigned int8 month; //1..12
   unsigned int8 day;   //1..31
   unsigned int8 dow;   //0..6
   unsigned int8 hour;  //0..23
   unsigned int8 min;   //0..59
   unsigned int8 sec;   //0..59
   //int1 valid;
} TIME_STRUCT;

//////////////////////////////////////////

#define PCF8563_I2C_ADDR   0xA2

// registers //
#define PCF8563_CONTROL1   0x00     //control/status 1
#define PCF8563_CONTROL2   0x01     //control/status 2
#define PCF8563_CLKOUT     0x0D     //CLKOUT control
#define PCF8563_TCONTROL   0x0E     //timer control
#define PCF8563_TIMER      0x0F     //timer countdown value

#define PCF8563_SECONDS    0x02     //0..59 BCD (bit7 is VL)
#define PCF8563_MINUTES    0x03     //0..59 BCD
#define PCF8563_HOURS      0x04     //0..23 bcd
#define PCF8563_DAYS       0x05     //1..31 bcd
#define PCF8563_WEEKDAY    0x06     //0..6
#define PCF8563_MONTHS     0x07     //0..12 (bit7 is Century, leave clear for 20xx)
#define PCF8563_YEARS      0x08     //0..99 bcd

#define PCF8563_MINUTE_ALARM  0x09  //0..59 BCD
#define PCF8563_HOUR_ALARM    0x0A  //0..23 BCD
#define PCF8563_DAY_ALARM     0x0B  //0..31 BCD
#define PCF8563_WEEKDAY_ALARM 0x0C  //0..6

static unsigned int8 _get_bcd(unsigned int8 data)
{
   unsigned int8 nibh;
   unsigned int8 nibl;

   nibh=data/10;
   nibl=data-(nibh*10);

   return((nibh<<4)|nibl);
}

static unsigned int8 _rm_bcd(unsigned int8 data)
{
   unsigned int8 i;

   i=data;
   data=(i>>4)*10;
   data=data+(i&0x0F);

   return data;
}

void rtc_init(void)
{
   i2c_start(STREAM_PCF8563);
   i2c_write(STREAM_PCF8563, PCF8563_I2C_ADDR);
   i2c_write(STREAM_PCF8563, PCF8563_CONTROL1);
   i2c_write(STREAM_PCF8563, 0x00);
   i2c_write(STREAM_PCF8563, 0x00);
   i2c_stop(STREAM_PCF8563);
}

void rtc_set_datetime(TIME_STRUCT *pTs)
{
   TIME_STRUCT ts;

   memcpy(&ts, pTs, sizeof(ts));

   i2c_start(STREAM_PCF8563);
   i2c_write(STREAM_PCF8563, PCF8563_I2C_ADDR);
   i2c_write(STREAM_PCF8563, PCF8563_SECONDS);
   i2c_write(STREAM_PCF8563, _get_bcd(ts.sec));
   i2c_write(STREAM_PCF8563, _get_bcd(ts.min));
   i2c_write(STREAM_PCF8563, _get_bcd(ts.hour));
   i2c_write(STREAM_PCF8563, _get_bcd(ts.day));
   i2c_write(STREAM_PCF8563, _get_bcd(ts.dow));
   i2c_write(STREAM_PCF8563, _get_bcd(ts.month));
   i2c_write(STREAM_PCF8563, _get_bcd(ts.year));
   i2c_stop(STREAM_PCF8563);
}

void rtc_get_datetime(TIME_STRUCT *pTs)
{
   TIME_STRUCT ts;
   unsigned int8 val;

   i2c_start(STREAM_PCF8563);
   i2c_write(STREAM_PCF8563, PCF8563_I2C_ADDR);
   i2c_write(STREAM_PCF8563, PCF8563_SECONDS);
   i2c_start(STREAM_PCF8563, 2);
   i2c_write(STREAM_PCF8563, PCF8563_I2C_ADDR | 1);
   val = i2c_read(STREAM_PCF8563, 1);
   //ts.valid = !bit_test(val, 7);
   ts.sec = _rm_bcd(val & 0x7F);
   ts.min = _rm_bcd(i2c_read(STREAM_PCF8563, 1) & 0x7F);
   ts.hour = _rm_bcd(i2c_read(STREAM_PCF8563, 1) & 0x3F);
   ts.day = _rm_bcd(i2c_read(STREAM_PCF8563, 1) & 0x3F);
   ts.dow = _rm_bcd(i2c_read(STREAM_PCF8563, 1) & 0x07);
   ts.month = _rm_bcd(i2c_read(STREAM_PCF8563, 1) & 0x1F);
   ts.year = _rm_bcd(i2c_read(STREAM_PCF8563, 0));
   i2c_stop(STREAM_PCF8563);
   
   memcpy(pTs, &ts, sizeof(ts));
}



#endif


But nothing I did fixed the problem. Then I tried the following:

* I programmed an old version of the HEX on my uC and it ran perfectly;
* I copied the project of this old version, and without changing any code, I just compiled and used the new HEX file to program the uC, and again it got stuck at the same place;
* I tried the same with 2 other projects I know it's working and uses the same PIC and code for the PCF8563. Both projects when I compile/build a new HEX file the same problem happens, but with the old HEX is running perfectly.

I haven't put the code here, since it looks like the compiler is the problem.
But if needed I can post it here.

Edit:
Important to say that the old versions were compiled with and old version of CCS: 5.015.
The version I'm using now is 5.105


Could be the ccs version or does anyone know why this could be happening?
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Nov 11, 2022 11:57 am     Reply with quote

Try specifying a speed in the I2C setup.
The default has changed on later compilers.
This should really always be specified, rather than relying on defaults.
Rigolon



Joined: 11 Nov 2022
Posts: 3

View user's profile Send private message

PostPosted: Fri Nov 11, 2022 12:46 pm     Reply with quote

I've tried specifying a speed and it didn't work.

But after researching for a while I found a solution.

My setup configurations have the following:

Code:
setup_spi(FALSE);


I commented it and now it's all working.

Not sure what is the problem and why before it wasn't a problem
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 11, 2022 5:18 pm     Reply with quote

There is only one MSSP module in the 18F452 and it runs both i2c and SPI.

The compiler configures the i2c in the startup code in main(). Example:
Code:

..... void main()
0026:  CLRF   TBLPTRU
0028:  BCF    RCON.IPEN
002A:  BSF    TRISC.-
002C:  BSF    TRISC.-
002E:  MOVLW  09
0030:  MOVWF  SSPADD
0032:  MOVLW  28
0034:  MOVWF  SSPCON1
0036:  BSF    SSPSTAT.SMP
0038:  BCF    SSPSTAT.CKE
003A:  BSF    ADCON1.PCFG0
003C:  BSF    ADCON1.PCFG1
003E:  BSF    ADCON1.PCFG2
0040:  BCF    ADCON1.PCFG3

But setup_spi(FALSE) comes after the startup code shown above.
So it will disable the MSSP module. Example:
Code:
...... {
...... setup_spi(FALSE);
0042:  CLRF   SSPCON1
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Nov 12, 2022 8:56 am     Reply with quote

Makes total sense.
As PCM says, the MSSP module handles both the I2C, and the SPI.
So you were turning the module off after it was setup. :(
Worth 'avoiding' mixing the two 'types' of setup.
Historically, the early compilers had SPI setup with setup_SPI. Now it
has #USE SPI, just as it does for I2C. So you are mixing an old format
SPI setup.
Rigolon



Joined: 11 Nov 2022
Posts: 3

View user's profile Send private message

PostPosted: Mon Nov 14, 2022 5:37 am     Reply with quote

Oh now I understand
Thank you both.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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