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