/** * \brief Initialize TWI master mode. * * \param p_twi Pointer to a TWI instance. * \param p_opt Options for initializing the TWI module (see \ref twi_options_t). * * \return TWI_SUCCESS if initialization is complete, error code otherwise. */ uint32_t twi_master_init(Twi *p_twi, const twi_options_t *p_opt) { uint32_t status = TWI_SUCCESS; /* Disable TWI interrupts */ p_twi->TWI_IDR = ~0UL; /* Dummy read in status register */ p_twi->TWI_SR; /* Reset TWI peripheral */ twi_reset(p_twi); twi_enable_master_mode(p_twi); /* Select the speed */ if (twi_set_speed(p_twi, p_opt->speed, p_opt->master_clk) == FAIL) { /* The desired speed setting is rejected */ status = TWI_INVALID_ARGUMENT; } if (p_opt->smbus == 1) { p_twi->TWI_CR = TWI_CR_QUICK; } return status; }
/** * \ingroup freertos_twi_peripheral_control_group * \brief Initializes the FreeRTOS ASF TWI (I2C) master driver for the specified * TWI port. * * freertos_twi_master_init() is an ASF specific FreeRTOS driver function. It * must be called before any other ASF specific FreeRTOS driver functions * attempt to access the same TWI port. * * If freertos_driver_parameters->operation_mode equals TWI_I2C_MASTER then * freertos_twi_master_init() will configure the TWI port for master mode * operation and enable the peripheral. If * freertos_driver_parameters->operation_mode equals any other value then * freertos_twi_master_init() will not take any action. * * Other ASF TWI functions can be called after freertos_twi_master_init() has * completed successfully. * * The FreeRTOS ASF driver both installs and handles the TWI PDC interrupts. * Users do not need to concern themselves with interrupt handling, and must * not install their own interrupt handler. * * This driver is provided with an application note, and an example project that * demonstrates the use of this function. * * \param p_twi The twi peripheral being initialized. * \param freertos_driver_parameters Defines the driver behavior. See the * freertos_peripheral_options_t documentation, and the application note that * accompanies the ASF specific FreeRTOS functions. * * \return If the initialization completes successfully then a handle that can * be used with FreeRTOS TWI read and write functions is returned. If * the initialisation fails then NULL is returned. */ freertos_twi_if freertos_twi_master_init(Twi *p_twi, const freertos_peripheral_options_t *const freertos_driver_parameters) { portBASE_TYPE twi_index; bool is_valid_operating_mode; freertos_twi_if return_value; const enum peripheral_operation_mode valid_operating_modes[] = {TWI_I2C_MASTER}; /* Find the index into the all_twi_definitions array that holds details of the p_twi peripheral. */ twi_index = get_pdc_peripheral_details(all_twi_definitions, MAX_TWIS, (void *) p_twi); /* Check the requested operating mode is valid for the peripheral. */ is_valid_operating_mode = check_requested_operating_mode( freertos_driver_parameters->operation_mode, valid_operating_modes, sizeof(valid_operating_modes) / sizeof(enum peripheral_operation_mode)); /* Don't do anything unless a valid p_twi pointer was used, and a valid operating mode was requested. */ if ((twi_index < MAX_TWIS) && (is_valid_operating_mode == true)) { /* This function must be called exactly once per supported twi. Check it has not been called before. */ configASSERT(memcmp((void *)&(tx_dma_control[twi_index]), &null_dma_control, sizeof(null_dma_control)) == 0); configASSERT(memcmp((void *)&(rx_dma_control[twi_index]), &null_dma_control, sizeof(null_dma_control)) == 0); /* Enable the peripheral's clock. */ pmc_enable_periph_clk( all_twi_definitions[twi_index].peripheral_id); /* Ensure everything is disabled before configuration. */ pdc_disable_transfer( all_twi_definitions[twi_index].pdc_base_address, (PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS)); twi_disable_interrupt( all_twi_definitions[twi_index].peripheral_base_address, MASK_ALL_INTERRUPTS); twi_reset( all_twi_definitions[twi_index].peripheral_base_address); switch (freertos_driver_parameters->operation_mode) { case TWI_I2C_MASTER: /* Call the standard ASF init function. */ twi_enable_master_mode( all_twi_definitions[twi_index].peripheral_base_address); break; default: /* No other modes are currently supported. */ break; } /* Create any required peripheral access mutexes and transaction complete semaphores. This peripheral is half duplex so only a single access mutex is required. */ create_peripheral_control_semaphores( freertos_driver_parameters->options_flags, &(tx_dma_control[twi_index]), &(rx_dma_control[twi_index])); /* Error interrupts are always enabled. */ twi_enable_interrupt( all_twi_definitions[twi_index].peripheral_base_address, IER_ERROR_INTERRUPTS); /* Configure and enable the TWI interrupt in the interrupt controller. */ configure_interrupt_controller( all_twi_definitions[twi_index].peripheral_irq, freertos_driver_parameters->interrupt_priority); return_value = (freertos_twi_if) p_twi; } else { return_value = NULL; } return return_value; }