Ejemplo n.º 1
0
/**
 * \brief Write multiple bytes to a TWI compatible slave device
 *
 * \param twim            Base address of the TWIM (i.e. &AVR32_TWIM).
 * \param *buffer         Data to be transmitted
 * \param nbytes          Number of bytes to be transmitted
 * \param saddr           Slave address
 * \param tenbit          Ten bit addressing
 * \retval STATUS_OK      If all bytes were send successfully
 * \retval ERR_IO_ERROR   NACK received or Bus Arbitration lost
 */
status_code_t twim_write (volatile avr32_twim_t *twim, uint8_t const *buffer,
		uint32_t nbytes, uint32_t saddr, bool tenbit)
{
	// Reset the TWIM module to clear the THR register
	twim->cr = AVR32_TWIM_CR_MEN_MASK;
	twim->cr = AVR32_TWIM_CR_SWRST_MASK;
	twim->cr = AVR32_TWIM_CR_MDIS_MASK;
	// Set pointer to TWIM instance for IT
	twim_inst = twim;
	// Disable the TWIM interrupts
	twim_disable_interrupt (twim_inst);
	// get a pointer to applicative data
	twim_tx_data = buffer;
	// set the number of bytes to transmit
	twim_tx_nb_bytes = nbytes;
	// Set next transfer to false
	twim_next = false;
	// Initialize bus transfer status
	transfer_status = TWI_SUCCESS;
	// set the command to start the transfer
	twim_inst->cmdr = (saddr << AVR32_TWIM_CMDR_SADR_OFFSET)
			| (nbytes << AVR32_TWIM_CMDR_NBYTES_OFFSET)
			| (AVR32_TWIM_CMDR_VALID_MASK)
			| (AVR32_TWIM_CMDR_START_MASK)
			| (AVR32_TWIM_CMDR_STOP_MASK)
			| ((tenbit ? 1 : 0) << AVR32_TWIM_CMDR_TENBIT_OFFSET)
			| (0 << AVR32_TWIM_CMDR_READ_OFFSET);
	// mask NACK and TXRDY interrupts
	twim_it_mask = AVR32_TWIM_IER_NAK_MASK | AVR32_TWIM_IER_TXRDY_MASK;
	// update IMR through IER
	twim_inst->ier = twim_it_mask;
	// Enable master transfer
	twim_inst->cr = AVR32_TWIM_CR_MEN_MASK;
	// Enable all interrupts
	cpu_irq_enable ();
	// send data
	while (!(transfer_status) && !(twim_status ())) {
		cpu_relax();
	}
#if AVR32_TWIM_H_VERSION > 101	// Removed in twim100 module due to IC bug
	// Disable master transfer
	twim->cr = AVR32_TWIM_CR_MDIS_MASK;
#endif
	if (transfer_status == TWI_RECEIVE_NACK
			|| transfer_status == TWI_ARBITRATION_LOST) {
		return ERR_IO_ERROR;
	}
	return STATUS_OK;
}
Ejemplo n.º 2
0
/**
 * \brief Perform Chained transfers to a TWI compatible slave device
 *
 * \param twim            Base address of the TWIM (i.e. &AVR32_TWIM)
 * \param *first          Information regarding first transfer
 * \param *second         Information regarding second transfer
 *                        (see \ref twim_transfer_t)
 * \param tenbit          To enable tenbit addressing
 * \retval STATUS_OK      Chain transfer successful
 * \retval ERR_IO_ERROR   NACK received or Bus Arbitration lost
 */
status_code_t twim_chained_transfer (volatile avr32_twim_t *twim,
		volatile twim_transfer_t *first,
		volatile twim_transfer_t *second, bool tenbit)
{
	// Reset the TWIM module to clear the THR register
	twim->cr = AVR32_TWIM_CR_MEN_MASK;
	twim->cr = AVR32_TWIM_CR_SWRST_MASK;
	twim->cr = AVR32_TWIM_CR_MDIS_MASK;
	// Set pointer to TWIM instance for IT
	twim_inst = twim;
	// Disable the TWIM interrupts
	twim_disable_interrupt (twim_inst);
	// Set next transfer to false
	twim_next = false;
	transfer_status = TWI_SUCCESS;
	if (tenbit && first->read) {
		twim->cmdr = (first->chip << AVR32_TWIM_CMDR_SADR_OFFSET)
				| (0 << AVR32_TWIM_CMDR_NBYTES_OFFSET)
				| (AVR32_TWIM_CMDR_VALID_MASK)
				| (AVR32_TWIM_CMDR_START_MASK)
				| (0 << AVR32_TWIM_CMDR_STOP_OFFSET)
				| (AVR32_TWIM_CMDR_TENBIT_MASK)
				| (0 << AVR32_TWIM_CMDR_READ_OFFSET);

		twim->ncmdr = (first->chip << AVR32_TWIM_CMDR_SADR_OFFSET)
				| (first->length << AVR32_TWIM_CMDR_NBYTES_OFFSET)
				| (AVR32_TWIM_CMDR_VALID_MASK)
				| (AVR32_TWIM_CMDR_START_MASK)
				| (0 << AVR32_TWIM_CMDR_STOP_OFFSET)
				| (AVR32_TWIM_CMDR_TENBIT_MASK)
				| (AVR32_TWIM_CMDR_REPSAME_MASK)
				| (AVR32_TWIM_CMDR_READ_MASK);
		while (!(twim->sr & AVR32_TWIM_SR_CCOMP_MASK)) {
			cpu_relax();
		}
		twim->scr = AVR32_TWIM_SR_CCOMP_MASK;
	} else {
		twim->cmdr = (first->chip << AVR32_TWIM_CMDR_SADR_OFFSET)
				| (first->length << AVR32_TWIM_CMDR_NBYTES_OFFSET)
				| (AVR32_TWIM_CMDR_VALID_MASK)
				| (AVR32_TWIM_CMDR_START_MASK)
				| (0 << AVR32_TWIM_CMDR_STOP_OFFSET)
				| ((tenbit ? 1 : 0) << AVR32_TWIM_CMDR_TENBIT_OFFSET)
				| ((first->read ? 1 : 0) << AVR32_TWIM_CMDR_READ_OFFSET);
	}

	twim->ncmdr = (second->chip << AVR32_TWIM_CMDR_SADR_OFFSET)
			| (second->length << AVR32_TWIM_CMDR_NBYTES_OFFSET)
			| (AVR32_TWIM_CMDR_VALID_MASK)
			| (AVR32_TWIM_CMDR_START_MASK)
			| (AVR32_TWIM_CMDR_STOP_MASK)
			| ((tenbit ? 1 : 0) << AVR32_TWIM_CMDR_TENBIT_OFFSET)
			| (((tenbit && second->read) ? 1 : 0)
			<< AVR32_TWIM_CMDR_REPSAME_OFFSET)
			| ((second->read ? 1 : 0) << AVR32_TWIM_CMDR_READ_OFFSET);

	if (first->read) {
		// get a pointer to applicative data
		twim_rx_data = first->buffer;
		// get data
		while (!(twim->sr & AVR32_TWIM_SR_CCOMP_MASK)) {
			if (twim->sr & AVR32_TWIM_SR_RXRDY_MASK) {
				*twim_rx_data++ = twim->rhr;
			}
		}
		if (twim->sr & AVR32_TWIM_SR_RXRDY_MASK) {
			*twim_rx_data++ = twim->rhr;
		}
	} else {
		// get a pointer to applicative data
		twim_tx_data = first->buffer;
		twim_tx_nb_bytes = first->length;
		// send data
		while (!(twim->sr & AVR32_TWIM_SR_CCOMP_MASK)) {
			if ((twim_tx_nb_bytes > 0) &&
					(twim->sr & AVR32_TWIM_SR_TXRDY_MASK)) {
				twim->thr = *twim_tx_data++;
				twim_tx_nb_bytes--;
			}
		}
	}

	twim->scr = AVR32_TWIM_SR_CCOMP_MASK;

	if (second->read) {
		// get a pointer to applicative data
		twim_rx_data = second->buffer;
		// get data
		while (!(twim->sr & AVR32_TWIM_SR_IDLE_MASK)) {
			if (twim->sr & AVR32_TWIM_SR_RXRDY_MASK) {
				*twim_rx_data++ = twim->rhr;
			}
		}
	} else {
		// get a pointer to applicative data
		twim_tx_data = second->buffer;

		twim_tx_nb_bytes = second->length;
		// send data
		while (!(twim->sr & AVR32_TWIM_SR_IDLE_MASK)) {
			if ((twim_tx_nb_bytes > 0) &&
					(twim->sr & AVR32_TWIM_SR_TXRDY_MASK)) {
			twim->thr = *twim_tx_data++;
			twim_tx_nb_bytes--;
			}
		}
	}

	if (twim->sr & AVR32_TWIM_SR_ARBLST_MASK) {
		twim->scr = AVR32_TWIM_SCR_ARBLST_MASK;
		return ERR_IO_ERROR;
	}

	if (twim->sr & AVR32_TWIM_SR_NAK_MASK) {
		twim->cmdr = twim->cmdr ^ AVR32_TWIM_CMDR_VALID_MASK;
		twim->scr = AVR32_TWIM_SCR_NAK_MASK;
		return ERR_IO_ERROR;
	}
	return STATUS_OK;
}
Ejemplo n.º 3
0
/**
 * \brief Write multiple bytes to a TWI compatible slave device
 *
 * \param twim            Base address of the TWIM (i.e. &AVR32_TWIM)
 * \param *package        Package information and data
 *                        (see \ref twim_package_t)
 * \retval STATUS_OK      If all bytes were send successfully
 * \retval ERR_IO_ERROR   NACK received or Bus Arbitration lost
 */
status_code_t twim_write_packet (volatile avr32_twim_t *twim,
		const twim_package_t *package)
{
	// Reset the TWIM module to clear the THR register
	twim->cr = AVR32_TWIM_CR_MEN_MASK;
	twim->cr = AVR32_TWIM_CR_SWRST_MASK;
	twim->cr = AVR32_TWIM_CR_MDIS_MASK;
	// Set pointer to TWIM instance for IT
	twim_inst = twim;
	// Disable the TWIM interrupts
	twim_disable_interrupt (twim_inst);
	// Initialize bus transfer status
	transfer_status = TWI_SUCCESS;
	// mask NACK and TXRDY interrupts
	twim_it_mask = AVR32_TWIM_IER_STD_MASK | AVR32_TWIM_IER_TXRDY_MASK;
	// Set next transfer to false
	twim_next = false;
	//check if internal address access is performed
	if (package->addr_length) {
		// selection of first valid byte of the address
		twim_tx_data = (uint8_t *) (&(package->addr));
		twim_tx_data += (4 - package->addr_length);
		// set the number of bytes to transmit
		twim_tx_nb_bytes = package->addr_length;
		// set next transfer to true
		twim_next = true;
		// Set the number of bytes & address for next transfer
		twim_package = package;
	} else {
	// get a pointer to applicative data
	twim_tx_data = package->buffer;
	// get a copy of nb bytes to write
	twim_tx_nb_bytes = package->length;
	}
	// initiate the transfer to send the data
	twim->cmdr = (package->chip << AVR32_TWIM_CMDR_SADR_OFFSET)
			| ((package->length + package->addr_length)
					<< AVR32_TWIM_CMDR_NBYTES_OFFSET)
			| (AVR32_TWIM_CMDR_VALID_MASK)
			| (AVR32_TWIM_CMDR_START_MASK)
			| (AVR32_TWIM_CMDR_STOP_MASK)
			| (0 << AVR32_TWIM_CMDR_READ_OFFSET);
	// update IMR through IER
	twim_inst->ier = twim_it_mask;
	// Enable master transfer
	twim_inst->cr = AVR32_TWIM_CR_MEN_MASK;
	// Enable all interrupts
	cpu_irq_enable ();
	// send data
	while (!(transfer_status) && !(twim_status ())) {
		cpu_relax();
	}
#if AVR32_TWIM_H_VERSION > 101	//Removed in twim100 module due to IC bug
	// Disable master transfer
	twim->cr = AVR32_TWIM_CR_MDIS_MASK;
#endif
	// Check for nack
	if (transfer_status == TWI_RECEIVE_NACK
			|| transfer_status == TWI_ARBITRATION_LOST) {
		return ERR_IO_ERROR;
	}
	return STATUS_OK;
}
Ejemplo n.º 4
0
/**
 * \brief Read multiple bytes from a TWI compatible slave device
 *
 * \param twim            Base address of the TWIM (i.e. &AVR32_TWIM)
 * \param *buffer         Received data
 * \param nbytes          Number of bytes to be transmitted
 * \param saddr           Slave address
 * \param tenbit          Ten bit addressing
 * \retval STATUS_OK      If all bytes were read successfully
 * \retval ERR_IO_ERROR   NACK received or Bus Arbitration lost
 */
status_code_t twim_read (volatile avr32_twim_t *twim, uint8_t *buffer,
		uint32_t nbytes, uint32_t saddr, bool tenbit)
{
	// Reset the TWIM module to clear the THR register
	twim->cr = AVR32_TWIM_CR_MEN_MASK;
	twim->cr = AVR32_TWIM_CR_SWRST_MASK;
	twim->cr = AVR32_TWIM_CR_MDIS_MASK;
	// Set pointer to TWIM instance for IT
	twim_inst = twim;
	// Disable the TWIM interrupts
	twim_disable_interrupt (twim_inst);
	// get a pointer to applicative data
	twim_rx_data = buffer;
	// get a copy of nb bytes to read
	twim_rx_nb_bytes = nbytes;
	// Set next transfer to false
	twim_next = false;
	// Initialize bus transfer status
	transfer_status = TWI_SUCCESS;
	//tenbit need special handling
	if (tenbit)	{
		twim_inst->cmdr = (saddr << AVR32_TWIM_CMDR_SADR_OFFSET)
				| (0 << AVR32_TWIM_CMDR_NBYTES_OFFSET)
				| (AVR32_TWIM_CMDR_VALID_MASK)
				| (AVR32_TWIM_CMDR_START_MASK)
				| (0 << AVR32_TWIM_CMDR_STOP_OFFSET)
				| (AVR32_TWIM_CMDR_TENBIT_MASK)
				| (0 << AVR32_TWIM_CMDR_READ_OFFSET);

		twim_inst->ncmdr = (saddr << AVR32_TWIM_CMDR_SADR_OFFSET)
				| (nbytes << AVR32_TWIM_CMDR_NBYTES_OFFSET)
				| (AVR32_TWIM_CMDR_VALID_MASK)
				| (AVR32_TWIM_CMDR_START_MASK)
				| (AVR32_TWIM_CMDR_STOP_MASK)
				| (AVR32_TWIM_CMDR_TENBIT_MASK)
				| (AVR32_TWIM_CMDR_REPSAME_MASK)
				| (AVR32_TWIM_CMDR_READ_MASK);
	} else {
		twim_inst->cmdr = (saddr << AVR32_TWIM_CMDR_SADR_OFFSET)
				| (nbytes << AVR32_TWIM_CMDR_NBYTES_OFFSET)
				| (AVR32_TWIM_CMDR_VALID_MASK)
				| (AVR32_TWIM_CMDR_START_MASK)
				| (AVR32_TWIM_CMDR_STOP_MASK)
				| (0 << AVR32_TWIM_CMDR_TENBIT_OFFSET)
				| (AVR32_TWIM_CMDR_READ_MASK);
	}
	// mask NACK and RXRDY interrupts
	twim_it_mask = AVR32_TWIM_IER_STD_MASK | AVR32_TWIM_IER_RXRDY_MASK;
	// update IMR through IER
	twim_inst->ier = twim_it_mask;
	// Enable master transfer
	twim_inst->cr = AVR32_TWIM_CR_MEN_MASK;
	// Enable all interrupts
	cpu_irq_enable ();
	// get data
	while (!(transfer_status) && !(twim_status ())) {
		cpu_relax();
	}
	// Disable master transfer
	twim->cr = AVR32_TWIM_CR_MDIS_MASK;
	//Check for nack
	if (transfer_status == TWI_RECEIVE_NACK
			|| transfer_status == TWI_ARBITRATION_LOST) {
		return ERR_IO_ERROR;
	}
	return STATUS_OK;
}
Ejemplo n.º 5
0
Archivo: twim.c Proyecto: Tjalling7/asf
int twim_write(volatile avr32_twim_t *twi, unsigned const char *buffer,
               int nbytes, int saddr, bool tenbit) {

    twim_disable_interrupt(twi);

    twim_nack = false;

    // get a pointer to applicative data
    twim_tx_data = buffer;

    twim_tx_nb_bytes = nbytes;

    twi->cmdr = (saddr << AVR32_TWIM_CMDR_SADR_OFFSET)
                | (nbytes << AVR32_TWIM_CMDR_NBYTES_OFFSET)
                | (1 << AVR32_TWIM_CMDR_VALID_OFFSET)
                | (1 << AVR32_TWIM_CMDR_START_OFFSET)
                | (1 << AVR32_TWIM_CMDR_STOP_OFFSET)
                | ((tenbit ? 1 : 0) << AVR32_TWIM_CMDR_TENBIT_OFFSET)
                | (0 << AVR32_TWIM_CMDR_READ_OFFSET);


    // mask NACK and TXRDY interrupts
    twim_it_mask = AVR32_TWIM_IER_ANAK_MASK | AVR32_TWIM_IER_TXRDY_MASK;

    // update IMR through IER
    twi->ier = twim_it_mask;

    // Set pointer to TWIM instance for IT
    twim_inst = twi;

    // Enable master transfer
    twi->cr =  AVR32_TWIM_CR_MEN_MASK;

#if AVR32_TWIM_H_VERSION > 101
    // put the byte in the Transmit Holding Register
    twim_inst->thr = *twim_tx_data++;
    // decrease transmitted bytes number
    twim_tx_nb_bytes--;
#endif

    // Enable all interrupts
    Enable_global_interrupt();

    // wait until Nack or IDLE in SR
    while (!twim_nack && !(twi->sr & AVR32_TWIM_SR_IDLE_MASK));

    // Disable master transfer
    twi->cr =  AVR32_TWIM_CR_MDIS_MASK;

#if AVR32_TWIM_H_VERSION > 101
    if( twim_nack ) {
        return TWI_RECEIVE_NACK;
    }
#else
    if( twi->sr & AVR32_TWIM_SR_ANAK_MASK ) {
        twi->scr = AVR32_TWIM_SCR_ANAK_MASK;
        return TWI_RECEIVE_NACK;
    }
#endif

    return TWI_SUCCESS;
}
Ejemplo n.º 6
0
Archivo: twim.c Proyecto: Tjalling7/asf
int twim_read(volatile avr32_twim_t *twi, unsigned char *buffer, int nbytes,
              int saddr, bool tenbit) {

    twim_disable_interrupt(twi);

    twim_nack = false;

    // get a pointer to applicative data
    twim_rx_data = buffer;

    //tenbit need special handling
    if (tenbit) {
        twi->cmdr = (saddr << AVR32_TWIM_CMDR_SADR_OFFSET)
                    | (0    << AVR32_TWIM_CMDR_NBYTES_OFFSET)
                    | (1 << AVR32_TWIM_CMDR_VALID_OFFSET)
                    | (1 << AVR32_TWIM_CMDR_START_OFFSET)
                    | (0 << AVR32_TWIM_CMDR_STOP_OFFSET)
                    | (1 << AVR32_TWIM_CMDR_TENBIT_OFFSET)
                    | (0 << AVR32_TWIM_CMDR_READ_OFFSET);

        twi->ncmdr = (saddr << AVR32_TWIM_CMDR_SADR_OFFSET)
                     | (nbytes << AVR32_TWIM_CMDR_NBYTES_OFFSET)
                     | (1      << AVR32_TWIM_CMDR_VALID_OFFSET)
                     | (1      << AVR32_TWIM_CMDR_START_OFFSET)
                     | (1      << AVR32_TWIM_CMDR_STOP_OFFSET)
                     | (1      << AVR32_TWIM_CMDR_TENBIT_OFFSET)
                     | (1      << AVR32_TWIM_CMDR_REPSAME_OFFSET)
                     | (1      << AVR32_TWIM_CMDR_READ_OFFSET);

    } else {
        twi->cmdr = (saddr  << AVR32_TWIM_CMDR_SADR_OFFSET)
                    | (nbytes << AVR32_TWIM_CMDR_NBYTES_OFFSET)
                    | (1      << AVR32_TWIM_CMDR_VALID_OFFSET)
                    | (1      << AVR32_TWIM_CMDR_START_OFFSET)
                    | (1      << AVR32_TWIM_CMDR_STOP_OFFSET)
                    | (0      << AVR32_TWIM_CMDR_TENBIT_OFFSET)
                    | (1      << AVR32_TWIM_CMDR_READ_OFFSET);

    }
    // get data

    // mask NACK and RXRDY interrupts
    twim_it_mask =  AVR32_TWIM_IER_ANAK_MASK | AVR32_TWIM_IER_TXRDY_MASK | AVR32_TWIM_IER_RXRDY_MASK;

    // update IMR through IER
    twi->ier = twim_it_mask;

    // Set pointer to TWIM instance for IT
    twim_inst = twi;

    // Enable master transfer
    twi->cr =  AVR32_TWIM_CR_MEN_MASK;

    // Enable all interrupts
    Enable_global_interrupt();

    // get data
    while (!twim_nack && !(twi->sr & AVR32_TWIM_SR_IDLE_MASK));

    // Disable master transfer
    twi->cr =  AVR32_TWIM_CR_MDIS_MASK;


    if( twim_nack )
    {
        return TWI_RECEIVE_NACK;
    }

    return TWI_SUCCESS;

}
Ejemplo n.º 7
0
Archivo: twim.c Proyecto: Tjalling7/asf
int twim_read_packet(volatile avr32_twim_t *twi, const twi_package_t *package) {

    twim_disable_interrupt(twi);

    twim_nack = false;

    // get a pointer to applicative data
    twim_rx_data = package->buffer;

    // get a copy of nb bytes to read
    twim_rx_nb_bytes = package->length;

    if (package->addr_length) {
        twim_tx_data = (unsigned char *) (&(package->addr));
        // selection of first valid byte of the address
        twim_tx_data += (4 - package->addr_length);

        twim_tx_nb_bytes = package->addr_length;

        twi->cmdr = (package->chip        << AVR32_TWIM_CMDR_SADR_OFFSET)
                    | (package->addr_length << AVR32_TWIM_CMDR_NBYTES_OFFSET)
                    | (1                    << AVR32_TWIM_CMDR_VALID_OFFSET)
                    | (1                    << AVR32_TWIM_CMDR_START_OFFSET)
                    | (0                    << AVR32_TWIM_CMDR_READ_OFFSET);

        twi->ncmdr = ((package->chip) << AVR32_TWIM_CMDR_SADR_OFFSET)
                     | (package->length << AVR32_TWIM_CMDR_NBYTES_OFFSET)
                     | (1               << AVR32_TWIM_CMDR_VALID_OFFSET)
                     | (1               << AVR32_TWIM_CMDR_START_OFFSET)
                     | (1               << AVR32_TWIM_CMDR_STOP_OFFSET)
                     | (1               << AVR32_TWIM_CMDR_READ_OFFSET);


    } else {
        twim_tx_nb_bytes = 0;
        twi->cmdr = (package->chip   << AVR32_TWIM_CMDR_SADR_OFFSET)
                    | (package->length<< AVR32_TWIM_CMDR_NBYTES_OFFSET)
                    | (1               << AVR32_TWIM_CMDR_VALID_OFFSET)
                    | (1               << AVR32_TWIM_CMDR_START_OFFSET)
                    | (1               << AVR32_TWIM_CMDR_STOP_OFFSET)
                    | (1               << AVR32_TWIM_CMDR_READ_OFFSET);
    }

    // mask NACK and RXRDY interrupts
    twim_it_mask =  AVR32_TWIM_IER_ANAK_MASK | AVR32_TWIM_IER_TXRDY_MASK | AVR32_TWIM_IER_RXRDY_MASK;

    // update IMR through IER
    twi->ier = twim_it_mask;

    // Set pointer to TWIM instance for IT
    twim_inst = twi;

    // Enable master transfer
    twi->cr =  AVR32_TWIM_CR_MEN_MASK;

    // Enable all interrupts
    Enable_global_interrupt();

    // get data
    while (!twim_nack && !(twi->sr & AVR32_TWIM_SR_IDLE_MASK));

    // Disable master transfer
    twi->cr =  AVR32_TWIM_CR_MDIS_MASK;


    if( twim_nack )
    {
        return TWI_RECEIVE_NACK;
    }

    return TWI_SUCCESS;
}
Ejemplo n.º 8
0
/**
 * \brief Read multiple bytes from a TWI compatible slave device
 *
 * \param twim            Base address of the TWIM (i.e. &AVR32_TWIM)
 * \param package         Package information and data
 *                        (see \ref twim_package_t)
 * \retval STATUS_OK      If all bytes were read successfully
 * \retval ERR_IO_ERROR   NACK received or Bus Arbitration lost
 */
status_code_t twim_read_packet (volatile avr32_twim_t *twim,
		const twim_package_t *package)
{
	// Disable master transfer
	twim->cr = AVR32_TWIM_CR_MDIS_MASK;
	// Set pointer to TWIM instance for IT
	twim_inst = twim;
	// Disable the TWIM interrupts
	twim_disable_interrupt (twim_inst);
	// get a pointer to applicative data
	twim_rx_data = package->buffer;
	// get a copy of nb bytes to read
	twim_rx_nb_bytes = package->length;
	// Set next write transfer to false
	twim_next = false;
	// Initialize bus transfer status
	transfer_status = TWI_SUCCESS;
	//check if internal address access is performed
	if (package->addr_length) {
		// Reset the TWIM module to clear the THR register
		twim_inst->cr = AVR32_TWIM_CR_MEN_MASK;
		twim_inst->cr = AVR32_TWIM_CR_SWRST_MASK;
		twim_inst->cr = AVR32_TWIM_CR_MDIS_MASK;
		// selection of first valid byte of the address
		twim_tx_data = package->addr;
		// set the number of bytes to transmit
		twim_tx_nb_bytes = package->addr_length;
		// mask NACK, TXRDY and RXRDY interrupts
		twim_it_mask = AVR32_TWIM_IER_STD_MASK |
				AVR32_TWIM_IER_TXRDY_MASK | AVR32_TWIM_IER_RXRDY_MASK;
		// Set the command register to initiate the transfer
		twim_inst->cmdr = (package->chip << AVR32_TWIM_CMDR_SADR_OFFSET)
				| (package->addr_length << AVR32_TWIM_CMDR_NBYTES_OFFSET)
				| (AVR32_TWIM_CMDR_VALID_MASK)
				| (AVR32_TWIM_CMDR_START_MASK)
				| (0 << AVR32_TWIM_CMDR_READ_OFFSET);
		// set the next command register to followup with the previous command
		twim_inst->ncmdr = ((package->chip) << AVR32_TWIM_CMDR_SADR_OFFSET)
				| (package->length << AVR32_TWIM_CMDR_NBYTES_OFFSET)
				| (AVR32_TWIM_CMDR_VALID_MASK)
				| (AVR32_TWIM_CMDR_START_MASK)
				| (AVR32_TWIM_CMDR_STOP_MASK)
				| (AVR32_TWIM_CMDR_READ_MASK);
	} else {
		twim_tx_nb_bytes = 0;
		// mask NACK and RXRDY interrupts
		twim_it_mask = AVR32_TWIM_IER_STD_MASK | AVR32_TWIM_IER_RXRDY_MASK;
		// Set the command register to initiate the transfer
		twim_inst->cmdr = (package->chip << AVR32_TWIM_CMDR_SADR_OFFSET)
				| (package->length << AVR32_TWIM_CMDR_NBYTES_OFFSET)
				| (AVR32_TWIM_CMDR_VALID_MASK)
				| (AVR32_TWIM_CMDR_START_MASK)
				| (AVR32_TWIM_CMDR_STOP_MASK)
				| (AVR32_TWIM_CMDR_READ_MASK);
	}
	// update IMR through IER
	twim_inst->ier = twim_it_mask;
	// Enable master transfer
	twim->cr = AVR32_TWIM_CR_MEN_MASK;
	// Enable all interrupts
	cpu_irq_enable ();
	// get data
	while (!(transfer_status) && !(twim_status ())) {
		cpu_relax();
	}
	// Disable master transfer
	twim->cr = AVR32_TWIM_CR_MDIS_MASK;
	if (transfer_status == TWI_RECEIVE_NACK
			|| transfer_status == TWI_ARBITRATION_LOST) {
		return ERR_IO_ERROR;
	}
	return STATUS_OK;
}