This file defines a useful set of functions for TWI on AVR32 devices.
Definition in file twi.c.
#include <avr32/io.h>
#include "compiler.h"
#include "intc.h"
#include "twi.h"
Go to the source code of this file.
Functions | |
void | twi_disable_interrupt (volatile avr32_twi_t *twi) |
Disable all TWI interrupts. | |
int | twi_master_init (volatile avr32_twi_t *twi, const twi_options_t *opt) |
Initialize the twi master module. | |
static void | twi_master_inst1_interrupt_handler (void) |
TWI interrupt handler. | |
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_probe (volatile avr32_twi_t *twi, char chip_addr) |
Test if a chip answers for a given twi address. | |
static int | twi_set_speed (volatile avr32_twi_t *twi, unsigned int speed, unsigned long pba_hz) |
Set the twi bus speed in cojunction with the clock frequency. | |
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. | |
static void | twi_slave_inst1_interrupt_handler (void) |
TWI interrupt handler. | |
Variables | |
static volatile avr32_twi_t * | twi_inst1 = &AVR32_TWI |
Pointer to the instance 1 of the TWI registers for IT. | |
static volatile unsigned long | twi_it_mask |
IT mask. | |
static volatile Bool | twi_nack = FALSE |
Add NACK boolean. | |
static volatile unsigned char *volatile | twi_rx_data = NULL |
Pointer to the applicative TWI receive buffer. | |
static volatile int | twi_rx_nb_bytes = 0 |
Remaining number of bytes to receive. | |
static twi_slave_fct_t | twi_slave_fct |
Pointer on TWI slave application routines. | |
static const unsigned char *volatile | twi_tx_data = NULL |
Pointer to the applicative TWI transmit buffer. | |
static volatile int | twi_tx_nb_bytes = 0 |
Remaining number of bytes to transmit. |
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 347 of file twi.c.
Referenced by twi_master_inst1_interrupt_handler().
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 }
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 258 of file twi.c.
References twi_options_t::chip, twi_options_t::pba_hz, twi_options_t::speed, twi_master_inst1_interrupt_handler(), twi_probe(), and twi_set_speed().
Referenced by main().
00259 { 00260 Bool global_interrupt_enabled = Is_global_interrupt_enabled(); 00261 int status; 00262 00263 // Disable TWI interrupts 00264 if (global_interrupt_enabled) Disable_global_interrupt(); 00265 twi->idr = ~0UL; 00266 twi->sr; 00267 00268 // Reset TWI 00269 twi->cr = AVR32_TWI_CR_SWRST_MASK; 00270 if (global_interrupt_enabled) Enable_global_interrupt(); 00271 00272 // Dummy read in SR 00273 status = twi->sr; 00274 00275 // Disable all interrupts 00276 Disable_global_interrupt(); 00277 00278 // Register TWI handler on level 2 00279 INTC_register_interrupt( &twi_master_inst1_interrupt_handler, AVR32_TWI_IRQ, AVR32_INTC_INT1); 00280 00281 // Enable all interrupts 00282 Enable_global_interrupt(); 00283 00284 // Select the speed 00285 twi_set_speed(twi, opt->speed, opt->pba_hz); 00286 00287 // Probe the component 00288 status = twi_probe(twi, opt->chip); 00289 00290 return status; 00291 }
static void twi_master_inst1_interrupt_handler | ( | void | ) | [static] |
TWI interrupt handler.
Definition at line 85 of file twi.c.
References twi_disable_interrupt(), twi_inst1, twi_it_mask, twi_nack, twi_rx_data, twi_rx_nb_bytes, twi_tx_data, and twi_tx_nb_bytes.
Referenced by twi_master_init().
00086 { 00087 // get masked status register value 00088 int status = twi_inst1->sr & twi_it_mask; 00089 00090 // this is a NACK 00091 if (status & AVR32_TWI_SR_NACK_MASK) 00092 { 00093 goto nack; 00094 } 00095 // this is a RXRDY 00096 else if (status & AVR32_TWI_SR_RXRDY_MASK) 00097 { 00098 // get data from Receive Holding Register 00099 *twi_rx_data = twi_inst1->rhr; 00100 twi_rx_data++; 00101 // last byte to receive 00102 if(--twi_rx_nb_bytes==1) 00103 { 00104 // set stop bit 00105 twi_inst1->cr = AVR32_TWI_STOP_MASK; 00106 } 00107 // receive complete 00108 if (twi_rx_nb_bytes==0) 00109 { 00110 // finish the receive operation 00111 goto complete; 00112 } 00113 } 00114 // this is a TXRDY 00115 else if (status & AVR32_TWI_SR_TXRDY_MASK) 00116 { 00117 // decrease transmited bytes number 00118 twi_tx_nb_bytes--; 00119 // no more bytes to transmit 00120 if (twi_tx_nb_bytes <= 0) 00121 { 00122 // enable TXCOMP IT and unmask all others IT 00123 twi_it_mask = AVR32_TWI_IER_TXCOMP_MASK; 00124 twi_inst1->ier = twi_it_mask; 00125 } 00126 else 00127 { 00128 // put the byte in the Transmit Holding Register 00129 twi_inst1->thr = *twi_tx_data++; 00130 } 00131 } 00132 // this is a TXCOMP 00133 else if (status & AVR32_TWI_SR_TXCOMP_MASK) 00134 { 00135 // finish the transmit operation 00136 goto complete; 00137 } 00138 00139 return; 00140 00141 nack: 00142 twi_nack = TRUE; 00143 00144 complete: 00145 // disable all interrupts 00146 twi_disable_interrupt(twi_inst1); 00147 00148 return; 00149 }
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 378 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_it_mask, twi_nack, TWI_RECEIVE_NACK, twi_rx_data, twi_rx_nb_bytes, and TWI_SUCCESS.
Referenced by main().
00379 { 00380 // check argument 00381 if (package->length == 0) 00382 { 00383 return TWI_INVALID_ARGUMENT; 00384 } 00385 00386 twi_nack = FALSE; 00387 00388 // set read mode, slave address and 3 internal address byte length 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 // set internal address for remote chip 00394 twi->iadr = package->addr; 00395 00396 // get a pointer to applicative data 00397 twi_rx_data = package->buffer; 00398 00399 // get a copy of nb bytes to read 00400 twi_rx_nb_bytes = package->length; 00401 00402 // Enable master transfer 00403 twi->cr = AVR32_TWI_CR_MSEN_MASK; 00404 00405 // Send start condition 00406 twi->cr = AVR32_TWI_START_MASK; 00407 00408 // only one byte to receive 00409 if(twi_rx_nb_bytes == 1) 00410 { 00411 // set stop bit 00412 twi->cr = AVR32_TWI_STOP_MASK; 00413 } 00414 00415 // mask NACK and RXRDY interrupts 00416 twi_it_mask = AVR32_TWI_IER_NACK_MASK | AVR32_TWI_IER_RXRDY_MASK; 00417 00418 // update IMR through IER 00419 twi->ier = twi_it_mask; 00420 00421 // get data 00422 while (!twi_nack && twi_rx_nb_bytes); 00423 00424 // Disable master transfer 00425 twi->cr = AVR32_TWI_CR_MSDIS_MASK; 00426 00427 if( twi_nack ) 00428 return TWI_RECEIVE_NACK; 00429 00430 return TWI_SUCCESS; 00431 }
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 434 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_it_mask, twi_nack, TWI_RECEIVE_NACK, TWI_SUCCESS, twi_tx_data, and twi_tx_nb_bytes.
Referenced by main(), and twi_probe().
00435 { 00436 // No data to send 00437 if (package->length == 0) 00438 { 00439 return TWI_INVALID_ARGUMENT; 00440 } 00441 00442 twi_nack = FALSE; 00443 00444 // Enable master transfer, disable slave 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 // set write mode, slave address and 3 internal address byte length 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 // set internal address for remote chip 00457 twi->iadr = package->addr; 00458 00459 // get a pointer to applicative data 00460 twi_tx_data = package->buffer; 00461 00462 // get a copy of nb bytes to write 00463 twi_tx_nb_bytes = package->length; 00464 00465 // put the first byte in the Transmit Holding Register 00466 twi_inst1->thr = *twi_tx_data++; 00467 00468 // mask NACK and TXRDY interrupts 00469 twi_it_mask = AVR32_TWI_IER_NACK_MASK | AVR32_TWI_IER_TXRDY_MASK; 00470 00471 // update IMR through IER 00472 twi->ier = twi_it_mask; 00473 00474 // send data 00475 while (!twi_nack && twi_tx_nb_bytes); 00476 00477 // Disable master transfer 00478 twi->cr = AVR32_TWI_CR_MSDIS_MASK; 00479 00480 if( twi_nack ) 00481 return TWI_RECEIVE_NACK; 00482 00483 return TWI_SUCCESS; 00484 }
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 358 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().
Referenced by twi_master_init().
00359 { 00360 twi_package_t package; 00361 char data[1] = {0}; 00362 00363 // data to send 00364 package.buffer = data; 00365 // chip address 00366 package.chip = chip_addr; 00367 // frame length 00368 package.length = 1; 00369 // address length 00370 package.addr_length = 0; 00371 // internal chip address 00372 package.addr = 0; 00373 // perform a master write access 00374 return (twi_master_write(twi, &package)); 00375 }
static int twi_set_speed | ( | volatile avr32_twi_t * | twi, | |
unsigned int | speed, | |||
unsigned long | pba_hz | |||
) | [static] |
Set the twi bus speed in cojunction with the clock frequency.
twi | Base address of the TWI (i.e. &AVR32_TWI). | |
speed | The desired twi bus speed | |
pba_hz | The current running PBA clock frequency |
Definition at line 236 of file twi.c.
References TWI_SUCCESS.
Referenced by twi_master_init(), and twi_slave_init().
00237 { 00238 unsigned int cldiv; 00239 unsigned int ckdiv = 0; 00240 00241 cldiv = (pba_hz / speed) - 4; 00242 00243 // cldiv must fit in 8 bits, ckdiv must fit in 3 bits 00244 while ((cldiv > 0xFF) && (ckdiv < 0x7)) 00245 { 00246 // increase clock divider 00247 ckdiv++; 00248 // divide cldiv value 00249 cldiv /= 2; 00250 } 00251 // set clock waveform generator register 00252 twi->cwgr = ( cldiv | (cldiv << AVR32_TWI_CWGR_CHDIV_OFFSET) | (ckdiv << AVR32_TWI_CWGR_CKDIV_OFFSET) ); 00253 00254 return TWI_SUCCESS; 00255 }
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 296 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.
00297 { 00298 Bool global_interrupt_enabled = Is_global_interrupt_enabled(); 00299 00300 // Disable TWI interrupts 00301 if (global_interrupt_enabled) Disable_global_interrupt(); 00302 twi->idr = ~0UL; 00303 twi->sr; 00304 00305 // Reset TWI 00306 twi->cr = AVR32_TWI_CR_SWRST_MASK; 00307 00308 if (global_interrupt_enabled) Enable_global_interrupt(); 00309 00310 // Dummy read in SR 00311 twi->sr; 00312 00313 // Disable all interrupts 00314 Disable_global_interrupt(); 00315 00316 // Register TWI handler on level 2 00317 INTC_register_interrupt( &twi_slave_inst1_interrupt_handler, AVR32_TWI_IRQ, AVR32_INTC_INT1); 00318 00319 // Enable all interrupts 00320 Enable_global_interrupt(); 00321 00322 // Select the speed 00323 twi_set_speed(twi, opt->speed, opt->pba_hz); 00324 00325 //** Link reception routine 00326 00327 // Disable master transfer, ensable slave 00328 twi->cr = AVR32_TWI_CR_MSDIS_MASK|AVR32_TWI_CR_SVEN_MASK; 00329 00330 // Set slave address 00331 twi->smr = (opt->chip << AVR32_TWI_SMR_SADR_OFFSET); 00332 00333 // get a pointer to applicative routines 00334 twi_slave_fct = *slave_fct; 00335 00336 // Slave Access Interrupt Enable 00337 twi_it_mask = AVR32_TWI_IER_SVACC_MASK; 00338 twi->ier = twi_it_mask; 00339 00340 // Everything went ok 00341 return TWI_SUCCESS; 00342 }
static void twi_slave_inst1_interrupt_handler | ( | void | ) | [static] |
TWI interrupt handler.
Definition at line 161 of file twi.c.
References twi_slave_fct_t::rx, twi_slave_fct_t::stop, twi_inst1, twi_it_mask, and twi_slave_fct_t::tx.
Referenced by twi_slave_init().
00162 { 00163 // get masked status register value 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 // Disable All interrupts 00170 twi_inst1->idr = AVR32_TWI_IDR_TXRDY_MASK|AVR32_TWI_IDR_RXRDY_MASK|AVR32_TWI_IER_EOSACC_MASK; 00171 // Reenable detection slave access 00172 twi_it_mask = AVR32_TWI_IER_SVACC_MASK; 00173 twi_inst1->ier = twi_it_mask; 00174 // Signal EOF access 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 // A slave is selected, then check direction 00183 if( status & AVR32_TWI_SR_SVREAD_MASK ) 00184 { 00185 // enable flag to signal data transmition 00186 twi_it_mask = AVR32_TWI_IER_TXRDY_MASK; 00187 twi_inst1->ier = twi_it_mask; 00188 // Transmit a data to master 00189 twi_inst1->thr = twi_slave_fct.tx(); 00190 }else{ 00191 // enable flag to signal data reception 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 // this is a RXRDY 00198 if( (twi_it_mask & AVR32_TWI_IER_RXRDY_MASK) 00199 && (status & AVR32_TWI_SR_RXRDY_MASK ) ) 00200 { 00201 // Get data from Receive Holding Register 00202 twi_slave_fct.rx( twi_inst1->rhr ); 00203 }else 00204 00205 // this is a TXRDY 00206 if( (twi_it_mask & AVR32_TWI_IER_TXRDY_MASK) 00207 && (status & AVR32_TWI_SR_TXRDY_MASK ) ) 00208 { 00209 // Byte transmited 00210 if( status & AVR32_TWI_SR_NACK_MASK ) 00211 { 00212 // Last Byte 00213 // Clear flag NACK 00214 twi_inst1->rhr; 00215 // Renable IT select slave 00216 twi_it_mask = AVR32_TWI_IER_EOSACC_MASK; 00217 twi_inst1->ier = twi_it_mask; 00218 }else{ 00219 // Transmit a data to master 00220 twi_inst1->thr = twi_slave_fct.tx(); 00221 } 00222 } 00223 return; 00224 }
volatile avr32_twi_t* twi_inst1 = &AVR32_TWI [static] |
Pointer to the instance 1 of the TWI registers for IT.
Definition at line 52 of file twi.c.
Referenced by twi_master_inst1_interrupt_handler(), twi_master_write(), and twi_slave_inst1_interrupt_handler().
volatile unsigned long twi_it_mask [static] |
IT mask.
Definition at line 68 of file twi.c.
Referenced by twi_master_inst1_interrupt_handler(), twi_master_read(), twi_master_write(), twi_slave_init(), and twi_slave_inst1_interrupt_handler().
volatile Bool twi_nack = FALSE [static] |
Add NACK boolean.
Definition at line 65 of file twi.c.
Referenced by twi_master_inst1_interrupt_handler(), twi_master_read(), and twi_master_write().
volatile unsigned char* volatile twi_rx_data = NULL [static] |
Pointer to the applicative TWI receive buffer.
Definition at line 57 of file twi.c.
Referenced by twi_master_inst1_interrupt_handler(), and twi_master_read().
volatile int twi_rx_nb_bytes = 0 [static] |
Remaining number of bytes to receive.
Definition at line 62 of file twi.c.
Referenced by twi_master_inst1_interrupt_handler(), and twi_master_read().
twi_slave_fct_t twi_slave_fct [static] |
const unsigned char* volatile twi_tx_data = NULL [static] |
Pointer to the applicative TWI transmit buffer.
Definition at line 55 of file twi.c.
Referenced by twi_master_inst1_interrupt_handler(), and twi_master_write().
volatile int twi_tx_nb_bytes = 0 [static] |
Remaining number of bytes to transmit.
Definition at line 60 of file twi.c.
Referenced by twi_master_inst1_interrupt_handler(), and twi_master_write().