Created
March 20, 2019 22:39
-
-
Save RozeDoyanawa/3271bc3f0569d9fcfebcbe77c20bd84b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define MAX_BUFFER 32 | |
// SLAVE | |
void I2C_SlaveInit(unsigned char addr); | |
void I2C_SlaveInterruptRoutine(void); | |
typedef struct _I2C_BufferInfo{ | |
unsigned char size; | |
unsigned char* buffer; | |
}I2C_BufferInfo; | |
void I2C_InputCallback(unsigned char buffer[], unsigned char count); | |
void I2C_OutputCallback(I2C_BufferInfo* bufferInfo); | |
// STRUCTURES | |
typedef struct _I2C_BaseData{ | |
char size; | |
unsigned char type; | |
} I2C_BaseData; | |
typedef struct _I2C_SingleChangeData{ | |
I2C_BaseData i2cbase; | |
char index; | |
char state; | |
} I2C_SingleChangeData; | |
typedef struct _I2C_UnitInfo{ | |
I2C_BaseData i2cbase; | |
char inputs; | |
char outputs; | |
}I2C_UnitInfo; | |
typedef struct _ARP { | |
unsigned long UDID; | |
unsigned char I2CAddress; | |
} ARP_INFO; | |
unsigned char inputBuffer[MAX_BUFFER]; | |
I2C_BufferInfo bufferInfo; | |
//char* bufferData; | |
//char expectedWriteSize = 0; | |
/**************************************************************************** | |
* Function: | |
* static void I2C_SlaveInit(unsigned char addr) | |
* | |
* Description: | |
* This routine initializes I2C in slave mode. | |
* | |
* | |
* Preconditions: | |
* None | |
* | |
* Parameters: | |
* None | |
* | |
* Returns: | |
* None | |
* | |
* Remarks: | |
* None | |
* | |
****************************************************************************/ | |
void I2C_SlaveInit(unsigned char addr){ | |
char temp; | |
SSP1CON1bits.WCOL = 0; | |
SSP1CON1bits.SSPOV = 0; | |
SSP1CON1bits.SSPEN = 0; | |
SSP1CON1bits.CKP = 1; | |
SSP1CON1bits.SSPM3 = 0; | |
SSP1CON1bits.SSPM2 = 1; | |
SSP1CON1bits.SSPM1 = 1; | |
SSP1CON1bits.SSPM0 = 0; | |
SSP1CON2bits.GCEN = 0; | |
SSP1CON2bits.RCEN = 0; | |
SSP1CON2bits.RSEN = 0; | |
SSP1CON2bits.SEN = 1; | |
//I2C_AHEN = 1; | |
//I2C_SDAHT = 1; | |
SSP1CON2bits.ACKSTAT = 0; | |
SSP1CON2bits.ACKDT = 0; | |
SSP1CON2bits.ACKEN = 0; | |
SSP1CON2bits.PEN = 0; | |
SSP1ADD = addr; | |
SSP1STATbits.SMP = 1; // Slew Rate Control Disabled (1Mhz) | |
temp = SSP1BUF; | |
PIR1bits.SSPIF = 0; | |
PIE1bits.SSPIE = 1; | |
SSP1CON1bits.SSPEN = 1; // Enable SSP | |
} | |
/**************************************************************************** | |
* Function: | |
* void I2C_SlaveInterruptRoutine(void) | |
* | |
* Description: | |
* This routine should be called when an interrupt was generated to | |
* check if it was I2C-related | |
* | |
* | |
* Preconditions: | |
* None | |
* | |
* Parameters: | |
* None | |
* | |
* Returns: | |
* None | |
* | |
* Remarks: | |
* None | |
* | |
****************************************************************************/ | |
void I2C_SlaveInterruptRoutine(void){ | |
if(PIR1bits.SSPIF && PIE1bits.SSPIE){ | |
char SSP_status = (SSP1STAT & 0b00101101); // Mask out State bits | |
char Temp; | |
static char Widx = 0; | |
static char Ridx = 0; | |
//LED_INT_B_IO = !LED_INT_B_IO; | |
switch(SSP_status) | |
{ | |
case 0b00001001: // I2C master write last byte was an address byte 0 0 A 0 S W 0 BF | |
if(SSP1CON1bits.SSPOV){ // Recive overflow | |
SSP1CON1bits.SSPOV = 0; | |
} | |
Temp = SSP1BUF; // Read out buffer to clear BF flag | |
Widx = 0; | |
break; | |
//case I2C_Write_Data2: | |
case 0b00101001: // I2C master write last byte was a data byte 0 0 D 0 S W 0 BF | |
if(SSP1CON1bits.SSPOV){ // Recive overflow | |
SSP1CON1bits.SSPOV = 0; | |
} | |
if( Widx >= sizeof(I2C_BaseData)){ | |
I2C_BaseData* i2cbase = (I2C_BaseData*)&inputBuffer; | |
if(i2cbase->size == Widx){ | |
Temp = SSP1BUF; // Read out buffer to clear BF flag | |
}else{ | |
inputBuffer[Widx++] = SSP1BUF; | |
} | |
if(i2cbase->size == Widx){ | |
I2C_InputCallback(inputBuffer, Widx); | |
} | |
}else{ | |
inputBuffer[Widx++] = SSP1BUF;// Store data in buffer | |
} | |
break; | |
case 0b00001101: // I2C master read last byte was an address byte 0 0 A 0 S R 0 0 | |
case 0b00001100: // I2C master read last byte was an address byte 0 0 A 0 S R 0 0 | |
I2C_OutputCallback(&bufferInfo); | |
SSP1BUF = bufferInfo.buffer[0]; // Write data to I2C | |
Ridx = 1; | |
break; | |
case 0b00101101: // I2C master read last byte was a data byte 0 0 D 0 S R 0 0 | |
case 0b00101100: // I2C master read last byte was a data byte 0 0 D 0 S R 0 0 | |
if(Ridx == bufferInfo.size){ // Prevent reading beond buffer | |
SSP1BUF = 0; // Write dummy data to I2C | |
}else{ | |
SSP1BUF = bufferInfo.buffer[Ridx++];// Write next data to I2C | |
} | |
if(SSP1CON1bits.WCOL){ // Writing while prev not | |
SSP1CON1bits.WCOL = 0; | |
} | |
break; | |
case 0b00101000: // I2C slave reset by nack from master 0 0 D 0 S W 0 0 | |
Temp = SSP1BUF; // Read out buffer to clear BF flag | |
break; | |
default: | |
Temp = SSP1BUF; // Read out buffer to clear BF flag | |
break; | |
} | |
PIR1bits.SSPIF = 0; // Clear activity flag | |
SSP1CON1bits.CKP = 1; // Enable clock | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment