00001
00069 #include "twi_slave_driver.h"
00070
00071
00080 void TWI_SlaveInitializeDriver(TWI_Slave_t *twi,
00081 TWI_t *module,
00082 void (*processDataFunction) (void))
00083 {
00084 twi->interface = module;
00085 twi->Process_Data = processDataFunction;
00086 twi->bytesReceived = 0;
00087 twi->bytesSent = 0;
00088 twi->status = TWIS_STATUS_READY;
00089 twi->result = TWIS_RESULT_UNKNOWN;
00090 twi->abort = false;
00091 }
00092
00093
00103 void TWI_SlaveInitializeModule(TWI_Slave_t *twi,
00104 uint8_t address,
00105 TWI_SLAVE_INTLVL_t intLevel)
00106 {
00107 twi->interface->SLAVE.CTRLA = intLevel |
00108 TWI_SLAVE_DIEN_bm |
00109 TWI_SLAVE_APIEN_bm |
00110 TWI_SLAVE_ENABLE_bm;
00111 twi->interface->SLAVE.ADDR = (address<<1);
00112 }
00113
00114
00122 void TWI_SlaveInterruptHandler(TWI_Slave_t *twi)
00123 {
00124 uint8_t currentStatus = twi->interface->SLAVE.STATUS;
00125
00126
00127 if (currentStatus & TWI_SLAVE_BUSERR_bm) {
00128 twi->bytesReceived = 0;
00129 twi->bytesSent = 0;
00130 twi->result = TWIS_RESULT_BUS_ERROR;
00131 twi->status = TWIS_STATUS_READY;
00132 }
00133
00134
00135 else if (currentStatus & TWI_SLAVE_COLL_bm) {
00136 twi->bytesReceived = 0;
00137 twi->bytesSent = 0;
00138 twi->result = TWIS_RESULT_TRANSMIT_COLLISION;
00139 twi->status = TWIS_STATUS_READY;
00140 }
00141
00142
00143 else if ((currentStatus & TWI_SLAVE_APIF_bm) &&
00144 (currentStatus & TWI_SLAVE_AP_bm)) {
00145
00146 TWI_SlaveAddressMatchHandler(twi);
00147 }
00148
00149
00150 else if (currentStatus & TWI_SLAVE_APIF_bm) {
00151 TWI_SlaveStopHandler(twi);
00152 }
00153
00154
00155 else if (currentStatus & TWI_SLAVE_DIF_bm) {
00156 TWI_SlaveDataHandler(twi);
00157 }
00158
00159
00160 else {
00161 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_FAIL);
00162 }
00163 }
00164
00171 void TWI_SlaveAddressMatchHandler(TWI_Slave_t *twi)
00172 {
00173
00174 if (twi->abort) {
00175 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
00176 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_ABORTED);
00177 twi->abort = false;
00178 } else {
00179 twi->status = TWIS_STATUS_BUSY;
00180 twi->result = TWIS_RESULT_UNKNOWN;
00181
00182
00183 uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00184 twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
00185
00186 twi->bytesReceived = 0;
00187 twi->bytesSent = 0;
00188
00189
00190 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
00191 }
00192 }
00193
00194
00199 void TWI_SlaveStopHandler(TWI_Slave_t *twi)
00200 {
00201
00202 uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00203 twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
00204
00205
00206 uint8_t currentStatus = twi->interface->SLAVE.STATUS;
00207 twi->interface->SLAVE.STATUS = currentStatus | TWI_SLAVE_APIF_bm;
00208
00209 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
00210
00211 }
00212
00213
00220 void TWI_SlaveDataHandler(TWI_Slave_t *twi)
00221 {
00222 if (twi->interface->SLAVE.STATUS & TWI_SLAVE_DIR_bm) {
00223 TWI_SlaveWriteHandler(twi);
00224 } else {
00225 TWI_SlaveReadHandler(twi);
00226 }
00227 }
00228
00229
00236 void TWI_SlaveReadHandler(TWI_Slave_t *twi)
00237 {
00238
00239 uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00240 twi->interface->SLAVE.CTRLA = currentCtrlA | TWI_SLAVE_PIEN_bm;
00241
00242
00243 if (twi->bytesReceived < TWIS_RECEIVE_BUFFER_SIZE) {
00244
00245 uint8_t data = twi->interface->SLAVE.DATA;
00246 twi->receivedData[twi->bytesReceived] = data;
00247
00248
00249 twi->Process_Data();
00250
00251 twi->bytesReceived++;
00252
00253
00254
00255
00256
00257 if (twi->abort) {
00258 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
00259 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_ABORTED);
00260 twi->abort = false;
00261 } else {
00262 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
00263 }
00264 }
00265
00266
00267
00268 else {
00269 twi->interface->SLAVE.CTRLB = TWI_SLAVE_ACKACT_bm |
00270 TWI_SLAVE_CMD_COMPTRANS_gc;
00271 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW);
00272 }
00273 }
00274
00275
00282 void TWI_SlaveWriteHandler(TWI_Slave_t *twi)
00283 {
00284
00285 if ((twi->bytesSent > 0) && (twi->interface->SLAVE.STATUS &
00286 TWI_SLAVE_RXACK_bm)) {
00287
00288 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
00289 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
00290 }
00291
00292 else {
00293 if (twi->bytesSent < TWIS_SEND_BUFFER_SIZE) {
00294 uint8_t data = twi->sendData[twi->bytesSent];
00295 twi->interface->SLAVE.DATA = data;
00296 twi->bytesSent++;
00297
00298
00299 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
00300 }
00301
00302 else {
00303 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
00304 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW);
00305 }
00306 }
00307 }
00308
00309
00317 void TWI_SlaveTransactionFinished(TWI_Slave_t *twi, uint8_t result)
00318 {
00319 twi->result = result;
00320 twi->status = TWIS_STATUS_READY;
00321 }