1 // ******************************************************************* 2 // I2C Master Library for Custom DPA Handlers * 3 // ******************************************************************* 4 // Copyright (c) IQRF Tech s.r.o. 5 // 6 // File: $RCSfile: I2Cmaster.c,v $ 7 // Version: $Revision: 1.5 $ 8 // Date: $Date: 2020/04/02 09:53:06 $ 9 // 10 // Revision history: 11 // 2020/01/02 Release for DPA 4.11 12 // 13 // ********************************************************************* 14 15 #ifndef __I2C_MASTER__ 16 #define __I2C_MASTER__ 17 18 //############################################################################################ 19 20 // Default I2C speed value. Redefine at your code if needed. 21 // #define I2Cfrequency 100000 22 23 // Define to keep value read by i2c_readXYZ in the global variable i2cReadData 24 // i2cReadData_GLOBAL 25 26 // I2C routines. Note: routines do not modify FSR1 27 void i2c_init(); 28 void i2c_shutdown(); 29 void i2c_waitForIdle(); 30 void i2c_start( uns8 address ); 31 void i2c_startAndWrite( uns8 i2cWriteData, uns8 address ); 32 void i2c_stop(); 33 uns8 i2c_read( bit ack ); 34 uns8 i2c_readACK(); 35 uns8 i2c_readNACK(); 36 uns8 i2c_readNACKandStop(); 37 void i2c_write( uns8 i2cWriteData ); // Note: also does not modify FSR0 38 void i2c_writeAndStop( uns8 i2cWriteData ); 39 40 #ifdef i2cReadData_GLOBAL 41 uns8 i2cReadData; 42 #endif 43 44 //############################################################################################ 45 #else 46 47 #pragma library 1 // Compile only used methods 48 49 // I2C SCL frequency [Hz] 50 #ifndef I2Cfrequency 51 #define I2Cfrequency 100000 52 #endif 53 54 #ifndef i2c_start_ENTRY 55 #define i2c_start_ENTRY() do {} while (0) 56 #endif 57 58 #ifndef i2c_stop_EXIT 59 #define i2c_stop_EXIT() do {} while (0) 60 #endif 61 62 #ifndef USE_FSRx 63 //############################################################################################ 64 void writeToSSPCON2( uns8 value ) 65 //############################################################################################ 66 { 67 writeToRAM( &SSPCON2, value ); 68 } 69 #else 70 #define writeToSSPCON2( value ) SSPCON2 = (value) 71 #endif 72 73 #ifndef USE_FSRx 74 //############################################################################################ 75 void writeOredToSSPCON2( uns8 value @ W ) 76 //############################################################################################ 77 { 78 writeToSSPCON2( SSPCON2 | value ); 79 } 80 #else 81 #define writeOredToSSPCON2( value ) SSPCON2 |= (value) 82 #endif 83 84 //############################################################################################ 85 void i2c_init() 86 //############################################################################################ 87 { 88 // SCL as input 89 TRISC.3 = 1; 90 // SDA as input 91 TRISC.4 = 1; 92 93 // I2C: Synchronous Serial Port Enable, I2C Master mode 94 #ifndef USE_FSRx 95 writeToRAM( &SSPCON1, 0b0010.1000 ); 96 #else 97 SSPCON1 = 0b0010.1000; 98 #endif 99 writeToSSPCON2( 0x00 ); 100 101 // I2C SCL frequency 102 SSPADD = ( F_OSC / I2Cfrequency / 4 ) - 1; 103 // Disable slew rate control 104 SMP = 1; 105 } 106 107 //############################################################################################ 108 void i2c_shutdown() 109 //############################################################################################ 110 { 111 // I2C master mode SSPCON = 0 112 #ifndef USE_FSRx 113 writeToRAM( &SSPCON1, 0x00 ); 114 #else 115 SSPCON1 = 0x00; 116 #endif 117 } 118 119 //############################################################################################ 120 #ifndef i2c_waitForIdle_REDEFINE 121 void i2c_waitForIdle() 122 //############################################################################################ 123 { 124 // Wait for idle and not writing 125 while ( ( SSPCON2 & 0b0001.1111 ) != 0 || RW_ ); 126 } 127 #endif 128 129 //############################################################################################ 130 void i2c_start( uns8 address ) 131 //############################################################################################ 132 { 133 i2c_start_ENTRY(); 134 135 i2c_waitForIdle(); 136 // SEN = 1 137 writeOredToSSPCON2( 0x01 ); 138 i2c_write( address ); 139 } 140 141 //############################################################################################ 142 void i2c_startAndWrite( uns8 i2cWriteData, uns8 address @ W ) 143 //############################################################################################ 144 { 145 i2c_start( address ); 146 i2c_write( i2cWriteData ); 147 } 148 149 //############################################################################################ 150 void i2c_stop() 151 //############################################################################################ 152 { 153 i2c_waitForIdle(); 154 // PEN = 1 155 writeOredToSSPCON2( 0x04 ); 156 157 i2c_stop_EXIT(); 158 } 159 160 //############################################################################################ 161 uns8 i2c_read( bit ack ) 162 //############################################################################################ 163 { 164 i2c_waitForIdle(); 165 // RCEN = 1 166 writeOredToSSPCON2( 0x08 ); 167 i2c_waitForIdle(); 168 169 #ifndef i2cReadData_GLOBAL 170 uns8 // Local, not global static variable 171 #endif 172 i2cReadData = SSPBUF; 173 174 i2c_waitForIdle(); 175 176 // Acknowledge, ACKDT = 0 177 writeToSSPCON2( SSPCON2 & ~0x20 ); 178 if ( !ack ) 179 // Not acknowledge, ACKDT = 1 180 writeOredToSSPCON2( 0x20 ); 181 182 // Send acknowledge sequence from ACKDT, ACKEN = 1 183 writeOredToSSPCON2( 0x10 ); 184 return i2cReadData; 185 } 186 187 //############################################################################################ 188 uns8 i2c_readACK() 189 //############################################################################################ 190 { 191 return i2c_read( TRUE ); 192 } 193 194 //############################################################################################ 195 uns8 i2c_readNACK() 196 //############################################################################################ 197 { 198 return i2c_read( FALSE ); 199 } 200 201 //############################################################################################ 202 uns8 i2c_readNACKandStop() 203 //############################################################################################ 204 { 205 uns8 data = i2c_readNACK(); 206 i2c_stop(); 207 return data; 208 } 209 210 //############################################################################################ 211 void i2c_write( uns8 i2cWriteData ) 212 //############################################################################################ 213 { 214 i2c_waitForIdle(); 215 SSPBUF = i2cWriteData; 216 } 217 218 //############################################################################################ 219 void i2c_writeAndStop( uns8 i2cWriteData @ W ) 220 //############################################################################################ 221 { 222 i2c_write( i2cWriteData ); 223 i2c_stop(); 224 } 225 //############################################################################################ 226 227 #pragma library 0 228 229 #endif 230 //############################################################################################