/** * \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; }
/** * \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; }
/** * \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; }
/** * \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; }