00001
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <avr32/io.h>
00046 #include "compiler.h"
00047 #include "intc.h"
00048 #include "twi.h"
00049
00050
00052 static volatile avr32_twi_t *twi_inst1 = &AVR32_TWI;
00053
00055 static const unsigned char *volatile twi_tx_data = NULL;
00057 static volatile unsigned char *volatile twi_rx_data = NULL;
00058
00060 static volatile int twi_tx_nb_bytes = 0;
00062 static volatile int twi_rx_nb_bytes = 0;
00063
00065 static volatile Bool twi_nack = FALSE;
00066
00068 static volatile unsigned long twi_it_mask;
00069
00070 #ifndef AVR32_TWI_180_H_INCLUDED
00071
00073 static twi_slave_fct_t twi_slave_fct;
00074
00075 #endif
00076
00077
00080 #if __GNUC__
00081 __attribute__((__interrupt__))
00082 #elif __ICCAVR32__
00083 __interrupt
00084 #endif
00085 static void twi_master_inst1_interrupt_handler(void)
00086 {
00087
00088 int status = twi_inst1->sr & twi_it_mask;
00089
00090
00091 if (status & AVR32_TWI_SR_NACK_MASK)
00092 {
00093 goto nack;
00094 }
00095
00096 else if (status & AVR32_TWI_SR_RXRDY_MASK)
00097 {
00098
00099 *twi_rx_data = twi_inst1->rhr;
00100 twi_rx_data++;
00101
00102 if(--twi_rx_nb_bytes==1)
00103 {
00104
00105 twi_inst1->cr = AVR32_TWI_STOP_MASK;
00106 }
00107
00108 if (twi_rx_nb_bytes==0)
00109 {
00110
00111 goto complete;
00112 }
00113 }
00114
00115 else if (status & AVR32_TWI_SR_TXRDY_MASK)
00116 {
00117
00118 twi_tx_nb_bytes--;
00119
00120 if (twi_tx_nb_bytes <= 0)
00121 {
00122
00123 twi_it_mask = AVR32_TWI_IER_TXCOMP_MASK;
00124 twi_inst1->ier = twi_it_mask;
00125 }
00126 else
00127 {
00128
00129 twi_inst1->thr = *twi_tx_data++;
00130 }
00131 }
00132
00133 else if (status & AVR32_TWI_SR_TXCOMP_MASK)
00134 {
00135
00136 goto complete;
00137 }
00138
00139 return;
00140
00141 nack:
00142 twi_nack = TRUE;
00143
00144 complete:
00145
00146 twi_disable_interrupt(twi_inst1);
00147
00148 return;
00149 }
00150
00151
00152 #ifndef AVR32_TWI_180_H_INCLUDED
00153
00156 #if __GNUC__
00157 __attribute__((__interrupt__))
00158 #elif __ICCAVR32__
00159 __interrupt
00160 #endif
00161 static void twi_slave_inst1_interrupt_handler(void)
00162 {
00163
00164 int status = twi_inst1->sr;
00165
00166 if( (twi_it_mask & AVR32_TWI_IER_EOSACC_MASK)
00167 && (status & AVR32_TWI_SR_EOSACC_MASK) )
00168 {
00169
00170 twi_inst1->idr = AVR32_TWI_IDR_TXRDY_MASK|AVR32_TWI_IDR_RXRDY_MASK|AVR32_TWI_IER_EOSACC_MASK;
00171
00172 twi_it_mask = AVR32_TWI_IER_SVACC_MASK;
00173 twi_inst1->ier = twi_it_mask;
00174
00175 twi_slave_fct.stop();
00176 }else
00177
00178 if( (twi_it_mask & AVR32_TWI_IER_SVACC_MASK)
00179 && (status & AVR32_TWI_SR_SVACC_MASK ) )
00180 {
00181 twi_inst1->idr = AVR32_TWI_IDR_SVACC_MASK;
00182
00183 if( status & AVR32_TWI_SR_SVREAD_MASK )
00184 {
00185
00186 twi_it_mask = AVR32_TWI_IER_TXRDY_MASK;
00187 twi_inst1->ier = twi_it_mask;
00188
00189 twi_inst1->thr = twi_slave_fct.tx();
00190 }else{
00191
00192 twi_it_mask = AVR32_TWI_IER_RXRDY_MASK|AVR32_TWI_IER_EOSACC_MASK;
00193 twi_inst1->ier = twi_it_mask;
00194 }
00195 }else
00196
00197
00198 if( (twi_it_mask & AVR32_TWI_IER_RXRDY_MASK)
00199 && (status & AVR32_TWI_SR_RXRDY_MASK ) )
00200 {
00201
00202 twi_slave_fct.rx( twi_inst1->rhr );
00203 }else
00204
00205
00206 if( (twi_it_mask & AVR32_TWI_IER_TXRDY_MASK)
00207 && (status & AVR32_TWI_SR_TXRDY_MASK ) )
00208 {
00209
00210 if( status & AVR32_TWI_SR_NACK_MASK )
00211 {
00212
00213
00214 twi_inst1->rhr;
00215
00216 twi_it_mask = AVR32_TWI_IER_EOSACC_MASK;
00217 twi_inst1->ier = twi_it_mask;
00218 }else{
00219
00220 twi_inst1->thr = twi_slave_fct.tx();
00221 }
00222 }
00223 return;
00224 }
00225
00226 #endif
00227
00228
00236 static int twi_set_speed(volatile avr32_twi_t *twi, unsigned int speed, unsigned long pba_hz)
00237 {
00238 unsigned int cldiv;
00239 unsigned int ckdiv = 0;
00240
00241 cldiv = (pba_hz / speed) - 4;
00242
00243
00244 while ((cldiv > 0xFF) && (ckdiv < 0x7))
00245 {
00246
00247 ckdiv++;
00248
00249 cldiv /= 2;
00250 }
00251
00252 twi->cwgr = ( cldiv | (cldiv << AVR32_TWI_CWGR_CHDIV_OFFSET) | (ckdiv << AVR32_TWI_CWGR_CKDIV_OFFSET) );
00253
00254 return TWI_SUCCESS;
00255 }
00256
00257
00258 int twi_master_init(volatile avr32_twi_t *twi, const twi_options_t *opt)
00259 {
00260 Bool global_interrupt_enabled = Is_global_interrupt_enabled();
00261 int status;
00262
00263
00264 if (global_interrupt_enabled) Disable_global_interrupt();
00265 twi->idr = ~0UL;
00266 twi->sr;
00267
00268
00269 twi->cr = AVR32_TWI_CR_SWRST_MASK;
00270 if (global_interrupt_enabled) Enable_global_interrupt();
00271
00272
00273 status = twi->sr;
00274
00275
00276 Disable_global_interrupt();
00277
00278
00279 INTC_register_interrupt( &twi_master_inst1_interrupt_handler, AVR32_TWI_IRQ, AVR32_INTC_INT1);
00280
00281
00282 Enable_global_interrupt();
00283
00284
00285 twi_set_speed(twi, opt->speed, opt->pba_hz);
00286
00287
00288 status = twi_probe(twi, opt->chip);
00289
00290 return status;
00291 }
00292
00293
00294 #ifndef AVR32_TWI_180_H_INCLUDED
00295
00296 int twi_slave_init(volatile avr32_twi_t *twi, const twi_options_t *opt, const twi_slave_fct_t *slave_fct)
00297 {
00298 Bool global_interrupt_enabled = Is_global_interrupt_enabled();
00299
00300
00301 if (global_interrupt_enabled) Disable_global_interrupt();
00302 twi->idr = ~0UL;
00303 twi->sr;
00304
00305
00306 twi->cr = AVR32_TWI_CR_SWRST_MASK;
00307
00308 if (global_interrupt_enabled) Enable_global_interrupt();
00309
00310
00311 twi->sr;
00312
00313
00314 Disable_global_interrupt();
00315
00316
00317 INTC_register_interrupt( &twi_slave_inst1_interrupt_handler, AVR32_TWI_IRQ, AVR32_INTC_INT1);
00318
00319
00320 Enable_global_interrupt();
00321
00322
00323 twi_set_speed(twi, opt->speed, opt->pba_hz);
00324
00325
00326
00327
00328 twi->cr = AVR32_TWI_CR_MSDIS_MASK|AVR32_TWI_CR_SVEN_MASK;
00329
00330
00331 twi->smr = (opt->chip << AVR32_TWI_SMR_SADR_OFFSET);
00332
00333
00334 twi_slave_fct = *slave_fct;
00335
00336
00337 twi_it_mask = AVR32_TWI_IER_SVACC_MASK;
00338 twi->ier = twi_it_mask;
00339
00340
00341 return TWI_SUCCESS;
00342 }
00343
00344 #endif
00345
00346
00347 void twi_disable_interrupt(volatile avr32_twi_t *twi)
00348 {
00349 Bool global_interrupt_enabled = Is_global_interrupt_enabled();
00350
00351 if (global_interrupt_enabled) Disable_global_interrupt();
00352 twi->idr = ~0UL;
00353 twi->sr;
00354 if (global_interrupt_enabled) Enable_global_interrupt();
00355 }
00356
00357
00358 int twi_probe(volatile avr32_twi_t *twi, char chip_addr)
00359 {
00360 twi_package_t package;
00361 char data[1] = {0};
00362
00363
00364 package.buffer = data;
00365
00366 package.chip = chip_addr;
00367
00368 package.length = 1;
00369
00370 package.addr_length = 0;
00371
00372 package.addr = 0;
00373
00374 return (twi_master_write(twi, &package));
00375 }
00376
00377
00378 int twi_master_read(volatile avr32_twi_t *twi, const twi_package_t *package)
00379 {
00380
00381 if (package->length == 0)
00382 {
00383 return TWI_INVALID_ARGUMENT;
00384 }
00385
00386 twi_nack = FALSE;
00387
00388
00389 twi->mmr = (package->chip << AVR32_TWI_MMR_DADR_OFFSET) |
00390 ((package->addr_length << AVR32_TWI_MMR_IADRSZ_OFFSET) & AVR32_TWI_MMR_IADRSZ_MASK) |
00391 (1 << AVR32_TWI_MMR_MREAD_OFFSET);
00392
00393
00394 twi->iadr = package->addr;
00395
00396
00397 twi_rx_data = package->buffer;
00398
00399
00400 twi_rx_nb_bytes = package->length;
00401
00402
00403 twi->cr = AVR32_TWI_CR_MSEN_MASK;
00404
00405
00406 twi->cr = AVR32_TWI_START_MASK;
00407
00408
00409 if(twi_rx_nb_bytes == 1)
00410 {
00411
00412 twi->cr = AVR32_TWI_STOP_MASK;
00413 }
00414
00415
00416 twi_it_mask = AVR32_TWI_IER_NACK_MASK | AVR32_TWI_IER_RXRDY_MASK;
00417
00418
00419 twi->ier = twi_it_mask;
00420
00421
00422 while (!twi_nack && twi_rx_nb_bytes);
00423
00424
00425 twi->cr = AVR32_TWI_CR_MSDIS_MASK;
00426
00427 if( twi_nack )
00428 return TWI_RECEIVE_NACK;
00429
00430 return TWI_SUCCESS;
00431 }
00432
00433
00434 int twi_master_write(volatile avr32_twi_t *twi, const twi_package_t *package)
00435 {
00436
00437 if (package->length == 0)
00438 {
00439 return TWI_INVALID_ARGUMENT;
00440 }
00441
00442 twi_nack = FALSE;
00443
00444
00445 twi->cr = AVR32_TWI_CR_MSEN_MASK
00446 #ifndef AVR32_TWI_180_H_INCLUDED
00447 | AVR32_TWI_CR_SVDIS_MASK
00448 #endif
00449 ;
00450
00451
00452 twi->mmr = (0 << AVR32_TWI_MMR_MREAD_OFFSET) |
00453 (package->chip << AVR32_TWI_MMR_DADR_OFFSET) |
00454 ((package->addr_length << AVR32_TWI_MMR_IADRSZ_OFFSET) & AVR32_TWI_MMR_IADRSZ_MASK);
00455
00456
00457 twi->iadr = package->addr;
00458
00459
00460 twi_tx_data = package->buffer;
00461
00462
00463 twi_tx_nb_bytes = package->length;
00464
00465
00466 twi_inst1->thr = *twi_tx_data++;
00467
00468
00469 twi_it_mask = AVR32_TWI_IER_NACK_MASK | AVR32_TWI_IER_TXRDY_MASK;
00470
00471
00472 twi->ier = twi_it_mask;
00473
00474
00475 while (!twi_nack && twi_tx_nb_bytes);
00476
00477
00478 twi->cr = AVR32_TWI_CR_MSDIS_MASK;
00479
00480 if( twi_nack )
00481 return TWI_RECEIVE_NACK;
00482
00483 return TWI_SUCCESS;
00484 }