00001
00067 #include "spi_driver.h"
00068
00069
00070
00087 void SPI_MasterInit(SPI_Master_t *spi,
00088 SPI_t *module,
00089 PORT_t *port,
00090 bool lsbFirst,
00091 SPI_MODE_t mode,
00092 SPI_INTLVL_t intLevel,
00093 bool clk2x,
00094 SPI_PRESCALER_t clockDivision)
00095 {
00096 spi->module = module;
00097 spi->port = port;
00098 spi->interrupted = false;
00099
00100 spi->module->CTRL = clockDivision |
00101 (clk2x ? SPI_CLK2X_bm : 0) |
00102 SPI_ENABLE_bm |
00103 (lsbFirst ? SPI_DORD_bm : 0) |
00104 SPI_MASTER_bm |
00105 mode;
00106
00107
00108 spi->module->INTCTRL = intLevel;
00109
00110
00111 spi->dataPacket = NULL;
00112
00113
00114 spi->port->DIRSET = SPI_MOSI_bm | SPI_SCK_bm;
00115 }
00116
00117
00118
00132 void SPI_SlaveInit(SPI_Slave_t *spi,
00133 SPI_t *module,
00134 PORT_t *port,
00135 bool lsbFirst,
00136 SPI_MODE_t mode,
00137 SPI_INTLVL_t intLevel)
00138 {
00139
00140 spi->module = module;
00141 spi->port = port;
00142
00143 spi->module->CTRL = SPI_ENABLE_bm |
00144 (lsbFirst ? SPI_DORD_bm : 0) |
00145 mode;
00146
00147
00148 spi->module->INTCTRL = intLevel;
00149
00150
00151 spi->port->DIRSET = SPI_MISO_bm;
00152 }
00153
00154
00155
00173 void SPI_MasterCreateDataPacket(SPI_DataPacket_t *dataPacket,
00174 const uint8_t *transmitData,
00175 uint8_t *receiveData,
00176 uint8_t bytesToTransceive,
00177 PORT_t *ssPort,
00178 uint8_t ssPinMask)
00179 {
00180 dataPacket->ssPort = ssPort;
00181 dataPacket->ssPinMask = ssPinMask;
00182 dataPacket->transmitData = transmitData;
00183 dataPacket->receiveData = receiveData;
00184 dataPacket->bytesToTransceive = bytesToTransceive;
00185 dataPacket->bytesTransceived = 0;
00186 dataPacket->complete = false;
00187 }
00188
00189
00190
00199 void SPI_MasterInterruptHandler(SPI_Master_t *spi)
00200 {
00201 uint8_t data;
00202 uint8_t bytesTransceived = spi->dataPacket->bytesTransceived;
00203
00204
00205
00206 if ( !(spi->module->CTRL & SPI_MASTER_bm) ) {
00207 spi->interrupted = true;
00208 }
00209
00210 else {
00211
00212
00213 data = spi->module->DATA;
00214 spi->dataPacket->receiveData[bytesTransceived] = data;
00215
00216
00217 bytesTransceived++;
00218
00219
00220 if (bytesTransceived < spi->dataPacket->bytesToTransceive) {
00221
00222 data = spi->dataPacket->transmitData[bytesTransceived];
00223 spi->module->DATA = data;
00224 }
00225
00226
00227 else {
00228
00229
00230 uint8_t ssPinMask = spi->dataPacket->ssPinMask;
00231 SPI_MasterSSHigh(spi->dataPacket->ssPort, ssPinMask);
00232
00233 spi->dataPacket->complete = true;
00234 }
00235 }
00236
00237 spi->dataPacket->bytesTransceived = bytesTransceived;
00238 }
00239
00240
00241
00255 uint8_t SPI_MasterInterruptTransceivePacket(SPI_Master_t *spi,
00256 SPI_DataPacket_t *dataPacket)
00257 {
00258 uint8_t data;
00259 bool interrupted = spi->interrupted;
00260
00261
00262 if (spi->dataPacket == NULL) {
00263 spi->dataPacket = dataPacket;
00264 }
00265
00266
00267 else if (spi->dataPacket->complete == false) {
00268 return (SPI_BUSY);
00269 }
00270
00271
00272 else if (interrupted) {
00273
00274 if (spi->port->OUT & SPI_SS_bm) {
00275
00276 interrupted = false;
00277 }
00278 else {
00279 return (SPI_INTERRUPTED);
00280 }
00281 }
00282
00283
00284
00285 spi->dataPacket = dataPacket;
00286 spi->dataPacket->complete = false;
00287 spi->interrupted = false;
00288
00289
00290 uint8_t ssPinMask = spi->dataPacket->ssPinMask;
00291 SPI_MasterSSLow(spi->dataPacket->ssPort, ssPinMask);
00292
00293 spi->dataPacket->bytesTransceived = 0;
00294
00295
00296 data = spi->dataPacket->transmitData[0];
00297 spi->module->DATA = data;
00298
00299
00300 return (SPI_OK);
00301 }
00302
00303
00324 uint8_t SPI_MasterTransceiveByte(SPI_Master_t *spi, uint8_t TXdata)
00325 {
00326
00327 spi->module->DATA = TXdata;
00328
00329
00330 while(!(spi->module->STATUS & SPI_IF_bm)) {
00331
00332 }
00333
00334 uint8_t result = spi->module->DATA;
00335
00336 return(result);
00337 }
00338
00339
00340
00354 bool SPI_MasterTransceivePacket(SPI_Master_t *spi,
00355 SPI_DataPacket_t *dataPacket)
00356 {
00357
00358 if(dataPacket == NULL) {
00359 return false;
00360 }
00361
00362
00363 spi->dataPacket = dataPacket;
00364
00365 uint8_t ssPinMask = spi->dataPacket->ssPinMask;
00366
00367
00368 if (spi->dataPacket->ssPort != NULL) {
00369
00370 SPI_MasterSSLow(spi->dataPacket->ssPort, ssPinMask);
00371 }
00372
00373
00374 uint8_t bytesTransceived = 0;
00375 uint8_t bytesToTransceive = dataPacket->bytesToTransceive;
00376 while (bytesTransceived < bytesToTransceive) {
00377
00378
00379 uint8_t data = spi->dataPacket->transmitData[bytesTransceived];
00380 spi->module->DATA = data;
00381
00382
00383 while(!(spi->module->STATUS & SPI_IF_bm)) {
00384
00385 }
00386
00387 data = spi->module->DATA;
00388 spi->dataPacket->receiveData[bytesTransceived] = data;
00389
00390 bytesTransceived++;
00391 }
00392
00393
00394 if (spi->dataPacket->ssPort != NULL) {
00395
00396 SPI_MasterSSHigh(spi->dataPacket->ssPort, ssPinMask);
00397 }
00398
00399
00400 spi->dataPacket->bytesTransceived = bytesTransceived;
00401 spi->dataPacket->complete = true;
00402
00403
00404 return true;
00405 }