EDF - OnePIC MCU
v1.1.0
|
00001 00016 #include "Compiler.h" 00017 #include "bsp.h" 00018 #include "TimeDelay.h" 00019 #include "OnePIC_i2c.h" 00020 00025 struct i2cBus bus1 = { 00026 I2C_IDLE, 00027 0,// no stopLock 00028 0,// offset 0 00029 (void *)0, 00030 &bus1.req 00031 }; 00032 00038 int i2cIdle(struct i2cBus *bus) 00039 { 00040 return bus->mstate == I2C_IDLE; 00041 } 00042 #if defined __PIC24F__ 00043 #define __I2C1_ISR __attribute__((interrupt, shadow, auto_psv)) 00047 void __I2C1_ISR _MI2C1Interrupt(void) 00048 #elif defined __PICC__ 00049 00052 void ISR_i2c(void) 00053 #elif defined(__PIC32MX__) 00054 00057 void ISR_i2c(void) 00058 #endif 00059 { 00060 struct trb *req = bus1.req; 00061 00062 I2C_INTERRUPT_FLAG = 0; // Clear Interrupt Flag 00063 if (req) 00064 { 00065 // Clear flag 00066 if (I2C_BCL_MASTER_BUS_COLLISION) 00067 { 00068 bus1.mstate = I2C_STARTING; // try again from scratch 00069 bus1.bufOffset = 0; 00070 I2C_BCL_MASTER_BUS_COLLISION = 0; 00071 I2C_SEN_START_CONDITION_ENABLE = 1; 00072 } 00073 else 00074 { 00075 Nop(); 00076 switch (bus1.mstate) 00077 { 00078 case I2C_IDLE: 00079 bus1.mstate = I2C_ERRORS; 00080 break; 00081 case I2C_STARTING: 00082 bus1.bufOffset = 0; 00083 if (req->txLen) 00084 { 00085 bus1.mstate = I2C_XMITING; 00086 I2C_TRANSMIT_REGISTER = (req->addr << 1); 00087 } 00088 else if (req->rxLen) 00089 { 00090 bus1.mstate = I2C_RECEIVEADDR; 00091 I2C_TRANSMIT_REGISTER = (req->addr << 1) | 1; 00092 } 00093 else 00094 { 00095 bus1.mstate = I2C_ERRORS; 00096 } 00097 break; 00098 case I2C_RESTARTING: 00099 bus1.mstate = I2C_RECEIVEADDR; 00100 I2C_TRANSMIT_REGISTER = (req->addr << 1) | 1; 00101 break; 00102 case I2C_XMITING: 00103 req->status = I2C_ACK_STATUS; 00104 if (bus1.bufOffset < req->txLen) 00105 { 00106 I2C_TRANSMIT_REGISTER = (req->txBuf[bus1.bufOffset++]); 00107 } 00108 else if (req->rxLen) 00109 { 00110 bus1.mstate = I2C_RESTARTING; 00111 I2C_REPEATED_START_ENABLE = 1; 00112 } 00113 else 00114 { 00115 bus1.mstate = I2C_STOPPING; 00116 Delay10us(5); // WARNING! : Delay in interrupt handler 00117 I2C_STOP_CONDITION_ENABLE = 1; 00118 } 00119 break; 00120 case I2C_RECEIVEADDR: 00121 req->status = I2C_ACK_STATUS; 00122 if (req->status) // NACKed 00123 { 00124 bus1.mstate = I2C_STOPPING; 00125 I2C_STOP_CONDITION_ENABLE = 1; 00126 } 00127 else // ACKed 00128 { 00129 bus1.mstate = I2C_RECEIVING; 00130 bus1.bufOffset = 0; 00131 I2C_RECIEVE_ENABLE = 1; 00132 } 00133 break; 00134 case I2C_RECEIVING: 00135 bus1.mstate = I2C_ACKING; 00136 req->rxBuf[bus1.bufOffset++] = I2C_RECIEVE_REGISTER; 00137 I2C_ACK_DATA = (bus1.bufOffset < req->rxLen) ? 0 : 1; 00138 I2C_ACK_SEQ_ENABLE = 1; 00139 break; 00140 case I2C_ACKING: 00141 if (bus1.bufOffset < req->rxLen) 00142 { 00143 bus1.mstate = I2C_RECEIVING; 00144 I2C_RECIEVE_ENABLE = 1; 00145 } 00146 else 00147 { 00148 bus1.mstate = I2C_STOPPING; 00149 I2C_STOP_CONDITION_ENABLE = 1; 00150 } 00151 break; 00152 case I2C_STOPPING: 00153 if ((req->status & 1) && req->retries) 00154 { 00155 --req->retries; 00156 bus1.mstate = I2C_STARTING; 00157 I2C_SEN_START_CONDITION_ENABLE = 1; 00158 } 00159 else 00160 { 00161 req->status |= 0x80; // set done bit 00162 if (bus1.stopLock) 00163 { 00164 bus1.mstate = I2C_STOP_IN_ENQ; 00165 } 00166 else if (req->next) 00167 { 00168 bus1.mstate = I2C_STARTING; 00169 bus1.req = req->next; 00170 I2C_SEN_START_CONDITION_ENABLE = 1; 00171 } 00172 else 00173 { 00174 bus1.mstate = I2C_IDLE; 00175 } 00176 } 00177 break; 00178 default: 00179 break; 00180 00181 } 00182 } 00183 } 00184 00185 } 00186 00187 00188 00189 00195 void trbEnQ(struct i2cBus *bus, struct trb *req) 00196 { 00197 req->status = 0; 00198 struct trb *reqTemp; 00199 if (bus->mstate == I2C_IDLE) 00200 { 00201 bus->mstate = I2C_STARTING; 00202 bus->req = req; 00203 bus->tail = &req->next; 00204 I2C_SEN_START_CONDITION_ENABLE = 1; 00205 } 00206 else 00207 { 00208 bus->stopLock = 1; 00209 *bus->tail = req; // add to queue 00210 bus->tail = &req->next; // advance the tail pointer 00211 bus->stopLock = 0; 00212 if (bus->mstate == I2C_STOP_IN_ENQ) // pretend we're in handler 00213 { 00214 reqTemp = bus->req->next; 00215 bus->mstate = I2C_STARTING; 00216 bus->req = reqTemp; 00217 // bus->req = 2; 00218 I2C_SEN_START_CONDITION_ENABLE = 1; 00219 } 00220 } 00221 } 00225 void I2CInit (void) 00226 { 00227 I2C_INTERRUPT_FLAG = 0; // clear interrupt 00228 I2C_INTERRUPT_ENABLE = 1; // enable I2C1 master interrupts 00229 //I2C master :: clock = Fosc / (4 * (SSPADD + 1))E 00230 #ifdef __PICC__ 00231 I2C_MODULE_SETUP_MASTER_3 = 1; 00232 I2C_MODULE_SETUP_MASTER_2 = 0; 00233 I2C_MODULE_SETUP_MASTER_1 = 0; 00234 I2C_MODULE_SETUP_MASTER_0 = 0; 00235 #endif 00236 #ifdef __PIC32MX__ 00237 INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR); 00238 INTEnableInterrupts(); 00239 INTSetVectorPriority(INT_I2C_1_VECTOR, INT_PRIORITY_LEVEL_4); 00240 INTClearFlag(INT_I2C1); 00241 INTClearFlag(INT_I2C1B); 00242 INTClearFlag(INT_I2C1M); 00243 INTEnable(INT_I2C1, INT_ENABLED); 00244 INTEnable(INT_I2C1B, INT_ENABLED); 00245 INTEnable(INT_I2C1M, INT_ENABLED); 00246 #endif // __PIC32mx__ 00247 00248 I2C_BRG = 0x27;//GetPeripheralClock() / I2CFREQ - 2; 00249 I2C_MODULE_ENABLE = 1; // enable I2C1 00250 I2C_DISABLE_SLEW_CONTROL = 1; 00251 }