Hey there StackOverflow!
My question concerns errors being reporting within the program pasted (far) below. The target device is the PIC12LF1552, it has one serial peripheral on it that I assumed could be used in conjunction with the library supplied with Microchip's XC8 compiler. Some sources on the internet have said that only higher end devices in the PIC18 line would support the library functions, other sources have said the library functions work just fine. So I decided that I didn't want to rewrite the I2C functions from scratch, nor did I want to write any amount of assembly for this project. Thus I settled on using the provided peripheral library that comes with XC8. I read up on the compiler documentation for how to source them (as seen in i2c.h
below). I know theres some error checking to do on those commands as per the documentation and some examples I've seen, but for the time being I'm assuming that both the master and the slave will behave perfectly just so I can get this thing off the ground.
I have included all relevant paths, which is why I assume it gets this far in the compilation process. My level of knowledge when it comes to the inner workings of a C language and compiler is very limited, I only know how to use these tools at a basic level, so there might be something fundamental I'm missing here.
Anyways, when I compile this code in MPLABX v1.95, I get this:
:0: error: undefined symbols:
_AckI2C(dist/pickit3/production\strobe.X.production.obj) _ReadI2C(dist/pickit3/production\strobe.X.production.obj) _IdleI2C(dist/pickit3/production\strobe.X.production.obj) _OpenI2C(dist/pickit3/production\strobe.X.production.obj) _StopI2C(dist/pickit3/production\strobe.X.production.obj) _NotAckI2C(dist/pickit3/production\strobe.X.production.obj) _WriteI2C(dist/pickit3/production\strobe.X.production.obj) _StartI2C(dist/pickit3/production\strobe.X.production.obj)
I couldn't find anything relevant on Google, StackOverflow, or otherwise concerning this problem from my specific context (another guy had a very similar issue when porting from Microchip's legacy C18 compiler, but I already did everything that guy did to solve his problem).
So I guess, the question is, why am I getting this compiler error, and what is the mechanism behind it in the C language or Microchip's implementation of it that is causing this?
/*
* File: i2c.h
* Author: James
*
* Created on July 23, 2014, 9:02 PM
*/
#ifndef I2C_H
#define I2C_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#include <plib\pconfig.h>
#include <plib\i2c.h>
#define SLAVE_ADDRESS 0b11110000
void Connect();
void Disconnect();
void Read(unsigned char address, unsigned char * data, unsigned char length);
void Write(unsigned char address, unsigned char * data, unsigned char length);
#endif /* I2C_H */
#include "i2c.h"
void Connect()
{
OpenI2C(MASTER, SLEW_OFF);
}
void Disconnect()
{
CloseI2C();
}
void Read(unsigned char address, unsigned char * data, unsigned char length)
{
IdleI2C(); // Wait until the bus is idle
StartI2C(); // Send START condition
IdleI2C(); // Wait for the end of the START condition
if (WriteI2C(SLAVE_ADDRESS | 0x01)) return; // Send slave address with R/W cleared for write
IdleI2C(); // Wait for ACK
if (WriteI2C(address)) return; // Send register address
IdleI2C(); // Wait for ACK
for(int i = 0; i < length; i++)
{
data[i] = ReadI2C(); // Write nth byte of data
AckI2C(); // Wait for ACK
}
NotAckI2C(); // Send NACK
StopI2C(); // Hang up, send STOP condition
}
void Write(unsigned char address, unsigned char * data, unsigned char length)
{
IdleI2C(); // Wait until the bus is idle
StartI2C(); // Send START condition
IdleI2C(); // Wait for the end of the START condition
if (WriteI2C(SLAVE_ADDRESS | 0x01)) return; // Send slave address with R/W cleared for write
IdleI2C(); // Wait for ACK
if (WriteI2C(address)) return; // Send register address
IdleI2C(); // Wait for ACK
for(int i = 0; i < length; i++)
{
WriteI2C(data[i]); // Write nth byte of data
IdleI2C(); // Wait for ACK
}
StopI2C(); // Hang up, send STOP condition
}
/*
* File: main.c
* Author: James
*
* Created on July 14, 2014, 11:00 PM
*/
/******************************************************************************/
/* Files to Include */
/******************************************************************************/
#if defined(__XC)
#include <xc.h> /* XC8 General Include File */
#endif
#include <stdint.h> /* For uint8_t definition */
#include <stdbool.h> /* For true/false definition */
#include <stdio.h>
#include <stdlib.h>
#include <pic12lf1552.h>
#include "i2c.h"
/******************************************************************************/
/* Defines */
/******************************************************************************/
//#define SYS_FREQ 16000000L
//#define FCY SYS_FREQ/4
#define _XTAL_FREQ 500000
__CONFIG
(
MCLRE_ON &
CP_OFF &
BOREN_OFF &
WDTE_OFF &
PWRTE_OFF &
FOSC_INTOSC
);
void main(void)
{
ANSELA = 0;
TRISA = 0b101111;
OPTION_REG = 0b01111111;
APFCONbits.SDSEL = 1;
unsigned char state = 0;
unsigned char count = 0;
unsigned char data[8] = { 0 };
Connect();
Read
(
0x01, // System register
data, // Data buffer
0x01 // Read length
);
LATAbits.LATA4 = data[0];
while(1)
{
switch (state)
{
case 0: // IDLE/OFF
if (LATAbits.LATA4) LATAbits.LATA4 = 0;
break;
case 1: // ON
if (!LATAbits.LATA4) LATAbits.LATA4 = 1;
break;
case 2: // BLINK (slow)
LATAbits.LATA4 = !LATAbits.LATA4;
__delay_ms(100);
break;
case 3: // BLINK (fast)
LATAbits.LATA4 = !LATAbits.LATA4;
__delay_ms(50);
break;
case 4: // BEAT DETECT
LATAbits.LATA4 = PORTAbits.RA5;
break;
default:
state = 0;
break;
}
if (TMR0 > 0)
{
while (count < 20)
{
if (!PORTAbits.RA2) count = 0;
__delay_ms(10);
count++;
}
TMR0 = 0;
state++;
}
}
}