PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
i2c_multmaster_rstring.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 #include "pic24_all.h"
30 
31 
32 /** \file
33 I2C Example: Demonstrates a PIC24 CPU
34 acting as an I2C slave. The PIC24 slave responds
35 to both write and read transactions.
36 */
37 
38 #define CPU1 1
39 #define CPU2 2
40 
41 #if (CPU_ID == CPU1)
42 #define SLAVE_I2C_ADDR 0x60
43 #define MY_ADDR 0x68
44 #else
45 #define SLAVE_I2C_ADDR 0x68
46 #define MY_ADDR 0x60
47 #endif
48 
49 typedef enum {
50  STATE_WAIT_FOR_ADDR,
51  STATE_WAIT_FOR_WRITE_DATA,
52 } STATE;
53 
54 volatile STATE e_mystate = STATE_WAIT_FOR_ADDR;
55 #define BUFSIZE 64
56 char sz_1[BUFSIZE];
57 char sz_2[BUFSIZE];
58 volatile uint8_t u8_gotString = 0;
59 volatile uint16_t u16_index;
60 
61 void _ISRFAST _SI2C1Interrupt(void) {
62  uint8_t u8_c;
63  _SI2C1IF = 0;
64  switch (e_mystate) {
65  case STATE_WAIT_FOR_ADDR:
66  u8_c = I2C1RCV; //clear RBF bit for address
67  u16_index = 0;
68  e_mystate = STATE_WAIT_FOR_WRITE_DATA;
69  break;
70  case STATE_WAIT_FOR_WRITE_DATA:
71  //character arrived, place in buffer
72  sz_1[u16_index++] = I2C1RCV; //read the byte
73  if (sz_1[u16_index-1] == 0) {
74  u8_gotString = 1; //set the semaphore
75  e_mystate = STATE_WAIT_FOR_ADDR; //wait for next transaction
76  }
77  break;
78  default:
79  e_mystate = STATE_WAIT_FOR_ADDR;
80  }
81 }
82 
83 int16_t getStringLength(char* psz_1) {
84  uint16_t u16_len;
85  u16_len = 0;
86  while (*psz_1) {
87  psz_1++;
88  u16_len++;
89  }
90  u16_len++; //contains length of string including null
91  return u16_len;
92 }
93 
94 void reverseString(char *psz_s1, char *psz_s2) {
95  char *psz_s1end;
96  if (!(*psz_s1)) {
97  *psz_s2 = 0; //psz_s1 is empty, return.
98  return;
99  }
100  psz_s1end = psz_s1;
101  //find end of first string
102  while (*psz_s1end) psz_s1end++;
103  psz_s1end--; //backup one to first non-zero byte
104  //now copy to S2 in reverse order
105  while (psz_s1end != psz_s1) {
106  *psz_s2 = *psz_s1end;
107  psz_s1end--;
108  psz_s2++;
109  }
110  //copy last byte
111  *psz_s2 = *psz_s1end;
112  psz_s2++;
113  //mark end of string
114  *psz_s2 = 0;
115 }
116 
117 
118 int main (void) {
119  uint16_t u16_len;
120  configBasic(HELLO_MSG);
121  configI2C1(400); //configure I2C for 400 KHz
122  I2C1ADD = MY_ADDR>>1; //initialize the address register
123  _SI2C1IF = 0;
124 #ifdef _SI2C1IP
125  _SI2C1IP = 1;
126 #else
127 #ifdef _SI2C1IP0
128  _SI2C1IP0 = 1; //header files can be inconsistent in how these are defined for PIC24H versus PIC24F
129  _SI2C1IP1 = 0;
130  _SI2C1IP2 = 0;
131 #endif
132 #endif
133 
134  _SI2C1IE = 1;
135  while (1) {
136  u8_gotString = 0; //clear semaphore
137 #if (CPU_ID == CPU1)
138  inStringEcho(sz_2,BUFSIZE); //get a string from the console
139  if (*sz_2 == 0) continue; //don't send empty string
140  u16_len = getStringLength(sz_2); //determine string length
141  writeNI2C1(SLAVE_I2C_ADDR,(uint8_t *)sz_2,u16_len); //send the string
142  //now wait for the reversed string to come back
143  while (!u8_gotString) doHeartbeat();
144  outString(sz_1);
145  outString("\n");
146 #else
147  while (!u8_gotString) doHeartbeat(); //wait from string from CPU1
148  reverseString(sz_1,sz_2); //reverse it
149  u16_len=getStringLength(sz_2);
150  writeNI2C1(SLAVE_I2C_ADDR,(uint8_t *)sz_2,u16_len); //send the string back
151 #endif
152 
153  }
154 }
155