This file defines a useful set of functions for TWI on AVR32 devices.
Definition in file twi.h.
#include <avr32/io.h>
#include "compiler.h"
Go to the source code of this file.
Data Structures | |
struct | twi_options_t |
Input parameters when initializing the twi module mode. More... | |
struct | twi_package_t |
Information concerning the data transmission. More... | |
struct | twi_slave_fct_t |
Pointer on TWI slave application routines. More... | |
Defines | |
Error Codes for the Module | |
#define | TWI_ARBITRATION_LOST -2 |
#define | TWI_BUSY -8 |
#define | TWI_INVALID_ARGUMENT -1 |
#define | TWI_NO_CHIP_FOUND -3 |
#define | TWI_RECEIVE_NACK -5 |
#define | TWI_RECEIVE_OVERRUN -4 |
#define | TWI_SEND_NACK -7 |
#define | TWI_SEND_OVERRUN -6 |
#define | TWI_SUCCESS 0 |
Functions | |
void | twi_disable_interrupt (volatile avr32_twi_t *twi) |
Disable all TWI interrupts. | |
Bool | twi_is_busy (void) |
Test if a TWI read/write is pending. | |
int | twi_master_init (volatile avr32_twi_t *twi, const twi_options_t *opt) |
Initialize the twi master module. | |
int | twi_master_read (volatile avr32_twi_t *twi, const twi_package_t *package) |
Read multiple bytes from a TWI compatible slave device. | |
int | twi_master_write (volatile avr32_twi_t *twi, const twi_package_t *package) |
Write multiple bytes to a TWI compatible slave device. | |
int | twi_master_write_ex (volatile avr32_twi_t *twi, const twi_package_t *package) |
Write multiple bytes to a TWI compatible slave device. This function is not blocking. | |
int | twi_probe (volatile avr32_twi_t *twi, char chip_addr) |
Test if a chip answers for a given twi address. | |
int | twi_slave_init (volatile avr32_twi_t *twi, const twi_options_t *opt, const twi_slave_fct_t *slave_fct) |
Initialize the twi slave module. |
#define TWI_BUSY -8 |
#define TWI_INVALID_ARGUMENT -1 |
Definition at line 59 of file twi.h.
Referenced by twi_master_read(), twi_master_write(), and twi_master_write_ex().
#define TWI_RECEIVE_NACK -5 |
Definition at line 63 of file twi.h.
Referenced by twi_master_read(), twi_master_write(), and twi_master_write_ex().
#define TWI_SUCCESS 0 |
Definition at line 58 of file twi.h.
Referenced by main(), twi_master_init(), twi_master_read(), twi_master_write(), twi_master_write_ex(), twi_set_speed(), and twi_slave_init().
void twi_disable_interrupt | ( | volatile avr32_twi_t * | twi | ) |
Disable all TWI interrupts.
twi | Base address of the TWI (i.e. &AVR32_TWI). |
Definition at line 353 of file twi.c.
Referenced by twi_master_inst1_interrupt_handler().
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 }
Bool twi_is_busy | ( | void | ) |
Test if a TWI read/write is pending.
Definition at line 550 of file twi.c.
References twi_nack, twi_rx_nb_bytes, and twi_tx_nb_bytes.
Referenced by twi_master_read(), and twi_master_write().
00551 { 00552 if( !twi_nack && ( twi_rx_nb_bytes || twi_tx_nb_bytes ) ) 00553 return TRUE; // Still receiving/transmitting... 00554 00555 else 00556 return FALSE; 00557 }
int twi_master_init | ( | volatile avr32_twi_t * | twi, | |
const twi_options_t * | opt | |||
) |
Initialize the twi master module.
twi | Base address of the TWI (i.e. &AVR32_TWI). | |
*opt | Options for initializing the twi module (see twi_options_t) |
Definition at line 264 of file twi.c.
References twi_options_t::pba_hz, twi_options_t::speed, twi_master_inst1_interrupt_handler(), twi_set_speed(), and TWI_SUCCESS.
Referenced by main().
00265 { 00266 Bool global_interrupt_enabled = Is_global_interrupt_enabled(); 00267 int status = TWI_SUCCESS; 00268 00269 // Disable TWI interrupts 00270 if (global_interrupt_enabled) Disable_global_interrupt(); 00271 twi->idr = ~0UL; 00272 twi->sr; 00273 00274 // Reset TWI 00275 twi->cr = AVR32_TWI_CR_SWRST_MASK; 00276 if (global_interrupt_enabled) Enable_global_interrupt(); 00277 00278 // Dummy read in SR 00279 twi->sr; 00280 00281 // Disable all interrupts 00282 Disable_global_interrupt(); 00283 00284 // Register TWI handler on level 2 00285 INTC_register_interrupt( &twi_master_inst1_interrupt_handler, AVR32_TWI_IRQ, AVR32_INTC_INT1); 00286 00287 // Enable all interrupts 00288 Enable_global_interrupt(); 00289 00290 // Select the speed 00291 twi_set_speed(twi, opt->speed, opt->pba_hz); 00292 00293 // Probe the component 00294 //status = twi_probe(twi, opt->chip); 00295 00296 return status; 00297 }
int twi_master_read | ( | volatile avr32_twi_t * | twi, | |
const twi_package_t * | package | |||
) |
Read multiple bytes from a TWI compatible slave device.
twi | Base address of the TWI (i.e. &AVR32_TWI). | |
package | Package information and data (see twi_package_t) |
Definition at line 384 of file twi.c.
References twi_package_t::addr, twi_package_t::addr_length, twi_package_t::buffer, twi_package_t::chip, twi_package_t::length, TWI_INVALID_ARGUMENT, twi_is_busy(), twi_it_mask, twi_nack, TWI_RECEIVE_NACK, twi_rx_data, twi_rx_nb_bytes, and TWI_SUCCESS.
Referenced by main().
00385 { 00386 // check argument 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 // set read mode, slave address and 3 internal address byte length 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 // set internal address for remote chip 00402 twi->iadr = package->addr; 00403 00404 // get a pointer to applicative data 00405 twi_rx_data = package->buffer; 00406 00407 // get a copy of nb bytes to read 00408 twi_rx_nb_bytes = package->length; 00409 00410 // Enable master transfer 00411 twi->cr = AVR32_TWI_CR_MSEN_MASK; 00412 00413 // Send start condition 00414 twi->cr = AVR32_TWI_START_MASK; 00415 00416 // only one byte to receive 00417 if(twi_rx_nb_bytes == 1) 00418 { 00419 // set stop bit 00420 twi->cr = AVR32_TWI_STOP_MASK; 00421 } 00422 00423 // mask NACK and RXRDY interrupts 00424 twi_it_mask = AVR32_TWI_IER_NACK_MASK | AVR32_TWI_IER_RXRDY_MASK; 00425 00426 // update IMR through IER 00427 twi->ier = twi_it_mask; 00428 00429 // get data 00430 while (!twi_nack && twi_rx_nb_bytes); 00431 00432 // Disable master transfer 00433 twi->cr = AVR32_TWI_CR_MSDIS_MASK; 00434 00435 if( twi_nack ) 00436 return TWI_RECEIVE_NACK; 00437 00438 return TWI_SUCCESS; 00439 }
int twi_master_write | ( | volatile avr32_twi_t * | twi, | |
const twi_package_t * | package | |||
) |
Write multiple bytes to a TWI compatible slave device.
twi | Base address of the TWI (i.e. &AVR32_TWI). | |
*package | Package information and data (see twi_package_t) |
Definition at line 442 of file twi.c.
References twi_package_t::addr, twi_package_t::addr_length, twi_package_t::buffer, twi_package_t::chip, twi_package_t::length, twi_inst1, TWI_INVALID_ARGUMENT, twi_is_busy(), twi_it_mask, twi_nack, TWI_RECEIVE_NACK, TWI_SUCCESS, twi_tx_data, and twi_tx_nb_bytes.
Referenced by main(), and twi_probe().
00443 { 00444 // No data to send 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 // Enable master transfer, disable slave 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 // set write mode, slave address and 3 internal address byte length 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 // set internal address for remote chip 00467 twi->iadr = package->addr; 00468 00469 // get a pointer to applicative data 00470 twi_tx_data = package->buffer; 00471 00472 // get a copy of nb bytes to write 00473 twi_tx_nb_bytes = package->length; 00474 00475 // put the first byte in the Transmit Holding Register 00476 twi_inst1->thr = *twi_tx_data++; 00477 00478 // mask NACK and TXRDY interrupts 00479 twi_it_mask = AVR32_TWI_IER_NACK_MASK | AVR32_TWI_IER_TXRDY_MASK; 00480 00481 // update IMR through IER 00482 twi->ier = twi_it_mask; 00483 00484 // send data 00485 while (!twi_nack && twi_tx_nb_bytes); 00486 00487 // Disable master transfer 00488 twi->cr = AVR32_TWI_CR_MSDIS_MASK; 00489 00490 if( twi_nack ) 00491 return TWI_RECEIVE_NACK; 00492 00493 return TWI_SUCCESS; 00494 }
int twi_master_write_ex | ( | volatile avr32_twi_t * | twi, | |
const twi_package_t * | package | |||
) |
Write multiple bytes to a TWI compatible slave device. This function is not blocking.
The function does not wait that all the bytes are written.
twi | Base address of the TWI (i.e. &AVR32_TWI). | |
*package | Package information and data (see twi_package_t) |
Definition at line 498 of file twi.c.
References twi_package_t::addr, twi_package_t::addr_length, twi_package_t::buffer, twi_package_t::chip, twi_package_t::length, TWI_BUSY, twi_inst1, TWI_INVALID_ARGUMENT, twi_it_mask, twi_nack, TWI_RECEIVE_NACK, TWI_SUCCESS, twi_tx_data, and twi_tx_nb_bytes.
00499 { 00500 int status = TWI_SUCCESS; 00501 00502 if( twi_nack ) 00503 status = TWI_RECEIVE_NACK; // Previous transaction returns a NACK 00504 00505 else if( twi_tx_nb_bytes ) 00506 return TWI_BUSY; // Still transmitting... 00507 00508 // No data to send 00509 if (package->length == 0) 00510 { 00511 return TWI_INVALID_ARGUMENT; 00512 } 00513 00514 twi_nack = FALSE; 00515 00516 // Enable master transfer, disable slave 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 // set write mode, slave address and 3 internal address byte length 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 // set internal address for remote chip 00529 twi->iadr = package->addr; 00530 00531 // get a pointer to applicative data 00532 twi_tx_data = package->buffer; 00533 00534 // get a copy of nb bytes to write 00535 twi_tx_nb_bytes = package->length; 00536 00537 // put the first byte in the Transmit Holding Register 00538 twi_inst1->thr = *twi_tx_data++; 00539 00540 // mask NACK and TXRDY interrupts 00541 twi_it_mask = AVR32_TWI_IER_NACK_MASK | AVR32_TWI_IER_TXRDY_MASK; 00542 00543 // update IMR through IER 00544 twi->ier = twi_it_mask; 00545 00546 return status; 00547 }
int twi_probe | ( | volatile avr32_twi_t * | twi, | |
char | chip_addr | |||
) |
Test if a chip answers for a given twi address.
twi | Base address of the TWI (i.e. &AVR32_TWI). | |
chip_addr | Address of the chip which is searched for |
Definition at line 364 of file twi.c.
References twi_package_t::addr, twi_package_t::addr_length, twi_package_t::buffer, twi_package_t::chip, twi_package_t::length, and twi_master_write().
00365 { 00366 twi_package_t package; 00367 char data[1] = {0}; 00368 00369 // data to send 00370 package.buffer = data; 00371 // chip address 00372 package.chip = chip_addr; 00373 // frame length 00374 package.length = 1; 00375 // address length 00376 package.addr_length = 0; 00377 // internal chip address 00378 package.addr = 0; 00379 // perform a master write access 00380 return (twi_master_write(twi, &package)); 00381 }
int twi_slave_init | ( | volatile avr32_twi_t * | twi, | |
const twi_options_t * | opt, | |||
const twi_slave_fct_t * | slave_fct | |||
) |
Initialize the twi slave module.
twi | Base address of the TWI (i.e. &AVR32_TWI). | |
*opt | Options for initializing the twi module (see twi_options_t) | |
*slave_fct | Pointer on application fonctions |
Definition at line 302 of file twi.c.
References twi_options_t::chip, twi_options_t::pba_hz, twi_options_t::speed, twi_it_mask, twi_set_speed(), twi_slave_inst1_interrupt_handler(), and TWI_SUCCESS.
00303 { 00304 Bool global_interrupt_enabled = Is_global_interrupt_enabled(); 00305 00306 // Disable TWI interrupts 00307 if (global_interrupt_enabled) Disable_global_interrupt(); 00308 twi->idr = ~0UL; 00309 twi->sr; 00310 00311 // Reset TWI 00312 twi->cr = AVR32_TWI_CR_SWRST_MASK; 00313 00314 if (global_interrupt_enabled) Enable_global_interrupt(); 00315 00316 // Dummy read in SR 00317 twi->sr; 00318 00319 // Disable all interrupts 00320 Disable_global_interrupt(); 00321 00322 // Register TWI handler on level 2 00323 INTC_register_interrupt( &twi_slave_inst1_interrupt_handler, AVR32_TWI_IRQ, AVR32_INTC_INT1); 00324 00325 // Enable all interrupts 00326 Enable_global_interrupt(); 00327 00328 // Select the speed 00329 twi_set_speed(twi, opt->speed, opt->pba_hz); 00330 00331 //** Link reception routine 00332 00333 // Disable master transfer, ensable slave 00334 twi->cr = AVR32_TWI_CR_MSDIS_MASK|AVR32_TWI_CR_SVEN_MASK; 00335 00336 // Set slave address 00337 twi->smr = (opt->chip << AVR32_TWI_SMR_SADR_OFFSET); 00338 00339 // get a pointer to applicative routines 00340 twi_slave_fct = *slave_fct; 00341 00342 // Slave Access Interrupt Enable 00343 twi_it_mask = AVR32_TWI_IER_SVACC_MASK; 00344 twi->ier = twi_it_mask; 00345 00346 // Everything went ok 00347 return TWI_SUCCESS; 00348 }