#include "pic24_all.h"
#define CPU1 1
#define CPU2 2
#if (CPU_ID == CPU1)
#define SLAVE_I2C_ADDR 0x60
#define MY_ADDR 0x68
#else
#define SLAVE_I2C_ADDR 0x68
#define MY_ADDR 0x60
#endif
typedef enum {
STATE_WAIT_FOR_ADDR,
STATE_WAIT_FOR_WRITE_DATA,
} STATE;
volatile STATE e_mystate = STATE_WAIT_FOR_ADDR;
#define BUFSIZE 64
char sz_1[BUFSIZE];
char sz_2[BUFSIZE];
volatile uint8_t u8_gotString = 0;
volatile uint16_t u16_index;
void _ISRFAST _SI2C1Interrupt(void) {
uint8_t u8_c;
_SI2C1IF = 0;
switch (e_mystate) {
case STATE_WAIT_FOR_ADDR:
u8_c = I2C1RCV; //clear RBF bit for address
u16_index = 0;
e_mystate = STATE_WAIT_FOR_WRITE_DATA;
break;
case STATE_WAIT_FOR_WRITE_DATA:
//character arrived, place in buffer
sz_1[u16_index++] = I2C1RCV; //read the byte
if (sz_1[u16_index-1] == 0) {
u8_gotString = 1; //set the semaphore
e_mystate = STATE_WAIT_FOR_ADDR; //wait for next transaction
}
break;
default:
e_mystate = STATE_WAIT_FOR_ADDR;
}
}
int16_t getStringLength(char* psz_1) {
uint16_t u16_len;
u16_len = 0;
while (*psz_1) {
psz_1++;
u16_len++;
}
u16_len++; //contains length of string including null
return u16_len;
}
void reverseString(char *psz_s1, char *psz_s2) {
char *psz_s1end;
if (!(*psz_s1)) {
*psz_s2 = 0; //psz_s1 is empty, return.
return;
}
psz_s1end = psz_s1;
//find end of first string
while (*psz_s1end) psz_s1end++;
psz_s1end--; //backup one to first non-zero byte
//now copy to S2 in reverse order
while (psz_s1end != psz_s1) {
*psz_s2 = *psz_s1end;
psz_s1end--;
psz_s2++;
}
//copy last byte
*psz_s2 = *psz_s1end;
psz_s2++;
//mark end of string
*psz_s2 = 0;
}
int main (void) {
uint16_t u16_len;
configBasic(HELLO_MSG);
configI2C1(400); //configure I2C for 400 KHz
I2C1ADD = MY_ADDR>>1; //initialize the address register
_SI2C1IF = 0;
#ifdef _SI2C1IP
_SI2C1IP = 1;
#else
#ifdef _SI2C1IP0
_SI2C1IP0 = 1; //header files can be inconsistent in how these are defined for PIC24H versus PIC24F
_SI2C1IP1 = 0;
_SI2C1IP2 = 0;
#endif
#endif
_SI2C1IE = 1;
while (1) {
u8_gotString = 0; //clear semaphore
#if (CPU_ID == CPU1)
inStringEcho(sz_2,BUFSIZE); //get a string from the console
if (*sz_2 == 0) continue; //don't send empty string
u16_len = getStringLength(sz_2); //determine string length
writeNI2C1(SLAVE_I2C_ADDR,(uint8_t *)sz_2,u16_len); //send the string
//now wait for the reversed string to come back
while (!u8_gotString) doHeartbeat();
outString(sz_1);
outString("\n");
#else
while (!u8_gotString) doHeartbeat(); //wait from string from CPU1
reverseString(sz_1,sz_2); //reverse it
u16_len=getStringLength(sz_2);
writeNI2C1(SLAVE_I2C_ADDR,(uint8_t *)sz_2,u16_len); //send the string back
#endif
}
}