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