/** * \brief Initialize TWIHS slave mode. * * \param p_twihs Pointer to a TWIHS instance. * \param ul_device_addr Device address of the SAM slave device on the I2C bus. */ void twihs_slave_init(Twihs *p_twihs, uint32_t ul_device_addr) { /* Disable TWIHS interrupts */ p_twihs->TWIHS_IDR = ~0UL; p_twihs->TWIHS_SR; /* Reset TWIHS */ twihs_reset(p_twihs); /* Set slave address in slave mode */ p_twihs->TWIHS_SMR = TWIHS_SMR_SADR(ul_device_addr); /* Enable slave mode */ twihs_enable_slave_mode(p_twihs); }
/** * \brief Initialize TWIHS master mode. * * \param p_twihs Pointer to a TWIHS instance. * \param p_opt Options for initializing the TWIHS module (see \ref twihs_options_t). * * \return TWIHS_SUCCESS if initialization is complete, error code otherwise. */ uint32_t twihs_master_init(Twihs *p_twihs, const twihs_options_t *p_opt) { uint32_t status = TWIHS_SUCCESS; /* Disable TWIHS interrupts */ p_twihs->TWIHS_IDR = ~0UL; /* Dummy read in status register */ p_twihs->TWIHS_SR; /* Reset TWIHS peripheral */ twihs_reset(p_twihs); twihs_enable_master_mode(p_twihs); /* Select the speed */ if (twihs_set_speed(p_twihs, p_opt->speed, p_opt->master_clk) == FAIL) { /* The desired speed setting is rejected */ status = TWIHS_INVALID_ARGUMENT; } return status; }
/** * \ingroup freertos_twihs_peripheral_control_group * \brief Initializes the FreeRTOS ASF TWIHS (I2C) master driver for the specified * TWIHS port. * * freertos_twihs_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 TWIHS port. * * If freertos_driver_parameters->operation_mode equals TWIHS_I2C_MASTER then * freertos_twihs_master_init() will configure the TWIHS port for master mode * operation and enable the peripheral. If * freertos_driver_parameters->operation_mode equals any other value then * freertos_twihs_master_init() will not take any action. * * Other ASF TWIHS functions can be called after freertos_twihs_master_init() has * completed successfully. * * The FreeRTOS ASF driver both installs and handles the TWIHS 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_twihs The twihs 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 TWIHS read and write functions is returned. If * the initialisation fails then NULL is returned. */ freertos_twihs_if freertos_twihs_master_init(Twihs *p_twihs, const freertos_peripheral_options_t *const freertos_driver_parameters) { portBASE_TYPE twihs_index; bool is_valid_operating_mode; freertos_twihs_if return_value; const enum peripheral_operation_mode valid_operating_modes[] = {TWIHS_I2C_MASTER}; /* Find the index into the all_twihs_definitions array that holds details of the p_twihs peripheral. */ twihs_index = get_pdc_peripheral_details(all_twihs_definitions, MAX_TWIHS, (void *) p_twihs); /* 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_twihs pointer was used, and a valid operating mode was requested. */ if ((twihs_index < MAX_TWIHS) && (is_valid_operating_mode == true)) { /* This function must be called exactly once per supported twihs. Check it has not been called before. */ configASSERT(memcmp((void *)&(tx_dma_control[twihs_index]), &null_dma_control, sizeof(null_dma_control)) == 0); configASSERT(memcmp((void *)&(rx_dma_control[twihs_index]), &null_dma_control, sizeof(null_dma_control)) == 0); /* Enable the peripheral's clock. */ pmc_enable_periph_clk( all_twihs_definitions[twihs_index].peripheral_id); /* Ensure everything is disabled before configuration. */ pdc_disable_transfer( all_twihs_definitions[twihs_index].pdc_base_address, (PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS)); twihs_disable_interrupt( all_twihs_definitions[twihs_index].peripheral_base_address, MASK_ALL_INTERRUPTS); twihs_reset( all_twihs_definitions[twihs_index].peripheral_base_address); switch (freertos_driver_parameters->operation_mode) { case TWIHS_I2C_MASTER: /* Call the standard ASF init function. */ twihs_enable_master_mode( all_twihs_definitions[twihs_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[twihs_index]), &(rx_dma_control[twihs_index])); /* Error interrupts are always enabled. */ twihs_enable_interrupt( all_twihs_definitions[twihs_index].peripheral_base_address, IER_ERROR_INTERRUPTS); /* Configure and enable the TWIHS interrupt in the interrupt controller. */ configure_interrupt_controller( all_twihs_definitions[twihs_index].peripheral_irq, freertos_driver_parameters->interrupt_priority); return_value = (freertos_twihs_if) p_twihs; } else { return_value = NULL; } return return_value; }