예제 #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;
}
예제 #2
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;
}
예제 #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;
}
예제 #4
0
파일: twim.c 프로젝트: InSoonPark/asf
/**
 * \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;
}