AVE...
I'm working on my first big project using XC8 compiler. This is also first time I'm using any C dialect.
I'm trying to write code for device that will work as I2C slave. Because I'm trying to do this on PIC16F1513, XC8 has no ready to use peripherial libraries (for some reason). So I tried to work something out using datasheet for that microcontroller. I tested this code by using ChipKIT Max32 with network shield and UECIDE programming environment. It doesn't work however, and I have no idea, why. I'm trying to read output buffer from my slave using this code for ChipKIT board:
Below are parts of code I wrote for PIC16F1513 with MPLAB X and XC8.
I2C related variables declaration:
Command resolve routine:
Main routine:
Interrupt routine:
I'm working on my first big project using XC8 compiler. This is also first time I'm using any C dialect.
I'm trying to write code for device that will work as I2C slave. Because I'm trying to do this on PIC16F1513, XC8 has no ready to use peripherial libraries (for some reason). So I tried to work something out using datasheet for that microcontroller. I tested this code by using ChipKIT Max32 with network shield and UECIDE programming environment. It doesn't work however, and I have no idea, why. I'm trying to read output buffer from my slave using this code for ChipKIT board:
Code:
#include <Wire.h>
long i = 0;
void setup() {
Wire.begin();
Serial0.begin(115200);
}
void loop() {
Serial0.println(i);
Wire.requestFrom(0xE1, 8);
while (Wire.available()) {
char c = Wire.read();
Serial0.print(c, BIN);
Serial0.print(' ');
}
Serial0.println();
i++;
delay(1000);
}
I2C related variables declaration:
C:
//Output buffer
volatile unsigned char outbuff[8];
//Input buffer
volatile struct {
unsigned char command :8;
unsigned char data0 :8;
unsigned char data1:8;
unsigned char data2:8;
}inbuff;
const unsigned char I2CADDR = 0xE1; //I2C address
C:
void CommandResolve(){
switch (inbuff.command){
case 0xA0 : R[0] = inbuff.data0; G[0] = inbuff.data1; B[0] = inbuff.data2; state = 1; break;
case 0xA1 : R[1] = inbuff.data0; G[1] = inbuff.data1; B[1] = inbuff.data2; state = 1; break;
case 0xA2 : R[2] = inbuff.data0; G[2] = inbuff.data1; B[2] = inbuff.data2; state = 1; break;
case 0xA3 : R[3] = inbuff.data0; G[3] = inbuff.data1; B[3] = inbuff.data2; state = 1; break;
case 0xA4 : R[4] = inbuff.data0; G[4] = inbuff.data1; B[4] = inbuff.data2; state = 1; break;
case 0xA5 : R[5] = inbuff.data0; G[5] = inbuff.data1; B[5] = inbuff.data2; state = 1; break;
case 0xA6 : R[6] = inbuff.data0; G[6] = inbuff.data1; B[6] = inbuff.data2; state = 1; break;
case 0xA7 : R[7] = inbuff.data0; G[7] = inbuff.data1; B[7] = inbuff.data2; state = 1; break;
case 0xAB : autocalenable(); break;
case 0xDE : testenable(); break;
case 0xDD: state = 0; break;
case 0xB0 : outbuff[0] = capar[0].caparst; outbuff[1] = capar[1].caparst; outbuff[2] = capar[2].caparst; outbuff[3] = capar[3].caparst;
outbuff[4] = capar[4].caparst; outbuff[5] = capar[5].caparst; outbuff[6] = capar[6].caparst; outbuff[7] = capar[7].caparst; break;
case 0xB1 : outbuff[0] = capar[8].caparst; outbuff[1] = capar[9].caparst; outbuff[2] = capar[10].caparst; outbuff[3] = capar[11].caparst;
outbuff[4] = capar[12].caparst; outbuff[5] = capar[13].caparst; outbuff[1] = capar[14].caparst; outbuff[7] = capar[15].caparst; break;
case 0xB2 : outbuff[0] = capar[16].caparst; outbuff[1] = capar[17].caparst; outbuff[2] = capar[18].caparst; outbuff[3] = capar[19].caparst;
outbuff[4] = capar[20].caparst; outbuff[5] = capar[21].caparst; outbuff[6] = capar[22].caparst; outbuff[7] = capar[23].caparst; break;
case 0xB3 : outbuff[0] = capar[24].caparst; outbuff[1] = capar[25].caparst; outbuff[2] = capar[26].caparst; outbuff[3] = capar[27].caparst;
outbuff[4] = capar[28].caparst; outbuff[5] = capar[29].caparst; outbuff[6] = capar[30].caparst; outbuff[7] = capar[31].caparst; break;
}
}
C:
void main(int argc, char** argv) {
//Clock init
OSCCON = 0x78;
OSCSTAT = 0x00;
//I/O Init
TRISA = 0;
TRISB = 0x2F;
TRISC = 0xF8;
ANSELB = 0x2F;
ANSELC = 0xE0;
//Interrupts
INTCONbits.PEIE = 1;
PIE1bits.SSPIE = 1;
//MSSP init
SSPCON1bits.SSPM = 0x6; //I2C Slave mode
SSPCON2bits.GCEN = 1; //General Call Interrupt
SSPCON2bits.SEN = 1;
SSPCON3bits.SDAHT = 1; //300ns SDA hold time for longer cables
SSPCON3bits.SCIE = 1; //Start condition enable bit
SSPADD = I2CADDR;
//Enables
SSPCON1bits.SSPEN = 1;
INTCONbits.GIE = 1;
while(1)
{
// State list
// 0 = CVD scan
// 1 = RGB scan
// 2 = Command resolve
// 3 = Autocalibration
// 4 = Test Routine
if (state>4) state = 0;
switch (state){
case 0: CVDScan; state = 1; break;
case 1: RGBScan; state = 0; break;
case 2: CommandResolve(); break;
case 3: autocal(); state = 0; break;
case 4: test(); state = 4; break;
}
}
}
C:
void interrupt myint()
{
unsigned char i;
if (SSPIE && SSPIF)
{
if (!SSPSTATbits.R_nW)
{
state = 2;
SSPIF = 0;
if (!SSPSTATbits.D_nA)
i = SSPBUF;
else
inbuff.command = SSPBUF;
if (SSPSTATbits.P) {
i = 0;
return;
}
CKP = 1;
while (!SSPIF);
SSPIF = 0;
inbuff.data0 = SSPBUF;
if (SSPSTATbits.P) {
i = 0;
return;
}
CKP = 1;
while (!SSPIF);
SSPIF = 0;
inbuff.data1 = SSPBUF;
if (SSPSTATbits.P) {
i = 0;
return;
}
CKP = 1;
while (!SSPIF);
SSPIF = 0;
inbuff.data2 = SSPBUF;
if (SSPSTATbits.P) {
i = 0;
return;
}
}
else
{
SSPIF = 0;
if (!SSPSTATbits.D_nA)
i = SSPBUF;
SSPSTATbits.R_nW = 1;
for (i = 0; i <8; i++)
{
SSPBUF = outbuff[i];
CKP = 1;
while (!SSPIF);
SSPIF = 0;
if (!ACKSTAT)
{
SSPIF = 0;
return;
}
}
}
}
}